C# 如何通过LINQ查询构建嵌套视图模型

C# 如何通过LINQ查询构建嵌套视图模型,c#,entity-framework,linq,C#,Entity Framework,Linq,下面的查询返回4行,所有行对应一个adres info,因此有一个ADRESYPE列,表示其家庭地址、工作地址等。 这是AllAddressViewModel: public class AllAddressViewModel { public AddressModel homeAddress{ get; set; } public AddressModel workAddress { get; set; } } public class

下面的查询返回4行,所有行对应一个adres info,因此有一个ADRESYPE列,表示其家庭地址、工作地址等。 这是AllAddressViewModel:

public class AllAddressViewModel
    {
        public AddressModel homeAddress{ get; set; }
        public AddressModel workAddress { get; set; }
    }

    public class AddressModel
    {
        public adresTypeEnum adresType{ get; set; }
        ...
这就是我正在尝试的

var result = (       from Muayene in muayeneRepo
                          join Adres in adresRepo on Muayene.HastaTc equals Adres.HastaTc
                          where Muayene.HastaTc == hastaTc.ToString() && Muayene.IsDeleted != true
                          select new HastaMuayeneKayitViewModel()
                          {
                              homeAddress= new AddressModel {
                                  adresType= Adres.AddressType,
                                  ...
                              },
                              workAddress = new AddressModel 
                              {
                                  adresType= Adres.AdresTipi,
                                  ...

我想你已经明白什么困扰我了,我应该把所有的地址和相应的视图模型匹配起来。。如何在linq中正确填充模型,不需要其他步骤

像Muayene/w 4个地址那样的连接将导致相同父记录的4个记录,每个记录有一个地址

如果地址记录具有区分字段地址类型,则第一步可能是将继承引入域模型,以便Muayene包含一个地址集合,但该集合将包含0-1个或多个作为从地址继承的不同实体类型的每个适用地址类型。通过这种方式,您可能更容易将这些转换为相应的视图模型。请参阅每个层次结构继承的表

为了构建视图模型结构,您需要按Muayene分组,以便为每个父级及其子级地址集合或更好的方式获得一个组,请使用导航属性来处理此问题

很难从代码示例中分辨出来,但如果muayeneRepo和addressRepo是基于数据库表返回IEnumerable或类似内容的存储库,这将是一个潜在的性能问题。通常情况下,您会从DBSET中提取这些数据。您还应该利用域中的导航属性,以便Muayene实体具有地址的ICollection

使用基于上下文的示例:

var muayenes = _context.Muayenes.Include(x => x.Addresses)
.Where(x => x.HastAc == hastAc && false == x.IsDeleted)
.ToList(); // Materializes these entities so further operations are Linq2Object
如果您没有导航属性,并且希望加入数据库集,那么您可以通过加入实体,然后执行GroupBy来完成相同的任务,其中group key是父实体,grouped Value是地址

我通常使用的下一步是添加构造函数或工厂类来处理从实体填充视图模型的新实例,或者连接类似AutoMapper的东西来完成这项工作。通常情况下,我只是自己将其连接起来,因为一般来说,遵循这些规则要比在其他地方查看映射规则,试图找出发生变化的原因更容易

例如:构造函数

var viewModels = muayenes.Select(x => new HastaMuayeneKayitViewModel(x)).ToList();
或工厂

var viewModels = muayens.Select(x => HastaMuayeneKayitViewModelFactory.Create(x)).ToList();
地址可以使用相同的原则构造


填充视图模型和子视图模型的逻辑可以转移到支持代码中,并重新使用,而不是以大型Linq表达式结束。

感谢您的详细回答和解释。