【问题标题】:How to merge two lists of different objects?如何合并两个不同对象的列表?
【发布时间】:2019-01-22 18:23:52
【问题描述】:

我有两个不同对象的数据实体类,例如-

class UserDetails
{
   int Id,
   DateTime DoB,
   string Name,
   .....
   .....
   .....
}

class Documents 
{
   int Id,
   int UserIdFK,
   string ImagePath,
   .....
   .....
}

我正在从下面的 LINQ 查询中获取数据-

var UserInfo = (from UserDetail in _userDBContext.UserDetails
                                             join doc in _userDBContext.Documents on UserDetail.Id equals doc.UserIdFK
                                             select new { UserDetail, doc }).ToList();

现在我在 UserInfo 列表中获取数据,但数据在 2 行中,第一行用于 UserDetails,第二行用于文档,如何将它们(userInfo 和文档数据)合并到一个列表中,只有一行。这样我就可以在 Razor Pages(前端)中使用该列表。

我什至创建了另一个对象,然后尝试将 UserInfo 列表项转换为新列表,但无法这样做,有什么方法可以将两个表的选定对象放入一个列表中。请帮我找到一个优雅的解决方案。

    public class UserKycCompositeModel
    {
       int Id,
       DateTime DoB,
       string Name,
       .......
       .......
       .......
       int Id,
       int UserIdFK,
       string ImagePath,
       .........
       .........
       .........
  }

【问题讨论】:

  • Documents 表和UserDetails 表之间是否存在多对一关系?

标签: c# asp.net-mvc list linq


【解决方案1】:

选择特定对象属性到您的复合对象中:

List<UserKycCompositeModel> userKycCompositeModels = (from UserDetail in _userDBContext.UserDetails
    join doc in _userDBContext.Documents on UserDetail.Id equals doc.UserIdFK
    select new UserKycCompositeModel { UserDetail.Id, UserDetail.Dob, **...etc.** }).ToList();

【讨论】:

  • 我第一个接受的答案!希望这次庆祝活动不会被视为违反评论规则的人。刚刚从臀部拍摄了这个。我以前从未使用过这种查询语法。很高兴它有帮助!
【解决方案2】:

最好创建一个特定的 ViewModel 来将其绑定到 View。 Window 上面的回答应该对你有用。如果您仍然想要一个通用列表,对查询稍作调整应该可以帮助您。

    var UserInfo = (from UserDetail in _userDBContext.UserDetails
                    join doc in _userDBContext.Documents 
                    on UserDetail.Id equals doc.UserIdFK
                    select new
                    {
                        UserId = UserDetail.Id,
                        DoB = UserDetail.DoB,
                        Name = UserDetail.Name,
                        DocId = doc.Id,
                        doc.UserIdFK,
                        doc.ImagePath
                    }).ToList();

【讨论】:

    【解决方案3】:

    如果Documents类和UserDetails类之间存在多对一的关系(意味着一个UserDetails类可以有多个Documents),那么最好给@ 987654325@类列表Documents

    List&lt;Documents&gt; 添加到UserDetails 类:

    public class UserDetails
    {
        public List<Documents> Documents { get; set; }
    }
    

    首先选择唯一的UserDetails

    var userDetails = from ud in _userDBCOntext.UserDetails
                      select ud;
    

    这将导致IEnumerable&lt;UserDetails&gt;。遍历 IEnumerable 并获取每个 UserDetails 实例的所有 Documents

    foreach (var userDetail in userDetails)
    {
        userDetail.Documets = from doc in _userDBContext.Documents
                              where userDetail.Id equals doc.UserIdFK
                              select doc;
    }
    

    现在您有一个IEnumerable&lt;UserDetails&gt;(名为userDetails),其中包含与之对应的所有Documents

    【讨论】:

      【解决方案4】:

      因为 var UserInfo 是一个列表。您不能/应该创建具有未定义属性的对象。

      如果您坚持使用这种方法,您可以按照 arun Mohan 所说的方式创建匿名对象。

      new {
         UserId = UserDetail.Id,
         DoB = UserDetail.DoB,
         Name = UserDetail.Name,
         DocId = doc.Id,
         doc.UserIdFK,
         doc.ImagePath
      }
      

      我不建议以这种方式使用新类 UserKycCompositeModel,但比拥有动态对象更好(作为性能和控制)。

      如果您想避免调用每个属性(如 UserID = UserDetail.ID),另一件事是使用反射,如下所示:

      UserKycCompositeModel newObj = new UserKycCompositeModel();
      
      foreach (var item in yourObject.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly))
      {
          propertyValue = item.GetValue(yourObject, null);
          Type myType = typeof(newObj);                   
          PropertyInfo myPropInfo = myType.GetProperty(item.Name);
          myPropInfo.SetValue(this, value, null);
      }
      

      我相信,有很多方法不能完全按照你的意愿去做,但取决于你将如何在你的逻辑业务中使用它,你可以用不同的方式来做。

      我更喜欢这样做:

      public class UserKycCompositeModel
      {
          public UserKycCompositeModel(UserDetails ud,Documents  doc)
          {
              this.UserDetails = ud;
              this.Document = doc;
          }
          public UserDetails UserDetails {get; private set;}
          public Documents Document {get; private set;}
      
      }
      

      然后以这种方式调用:

      var UserInfo = (from UserDetail in _userDBContext.UserDetails
                           join doc in _userDBContext.Documents on UserDetail.Id equals doc.UserIdFK
                           select new UserKycCompositeModel(UserDetail, doc)).ToList();
      

      并使用 UserInfo.UserDetails 或 UserInfo.Documents 等用户信息。

      有更多的方法,但也许你必须解释为什么你想要它,或者看看你是否想按照正常的方式来使用实体。

      【讨论】:

        猜你喜欢
        • 2021-09-10
        • 2018-04-21
        • 2019-09-08
        • 2019-06-09
        • 2022-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多