【问题标题】:Linq EF Include() with Select() new type lost includedLinq EF Include() with Select() new type lost include
【发布时间】:2016-03-17 21:26:13
【问题描述】:
context.Projects
.Include(x => x.Members) //List<Member> public class Member
.Include(x => x.Members.Select(z => z.City)) //public class City
.ToList(); 

项目中选择

包括project.Members列表

包括每个project.Members.City

需要在结果中添加一些数据

context.Projects
.Include(x => x.Members) 
.Include(x => x.Members.Select(z => z.City)) 
.Select(x => new {
    Project = x,
    Amount = 22
})
.ToList(); 

Project 属性已填充,但 Members 为空

问题 1 - 如何在 new { Project = x }

中包含 Project.Members

下一个

context.Projects
.Include(x => x.Members) //List<Member>
.Include(x => x.Members.Select(z => z.City)) //City is navigation property
.Select(x => new {
    Project = x,
    Members = x.Members,
    Amount = 22
})
.ToList(); 

Project 属性已填充,Members 已填充,但 Members[0].City 为空

问题 2 - 如何填写 Members[0].City

附言

实体框架 6

public class Project
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public List<ProjectMember> Members { get; set; }
}

public class ProjectMember
{
    public Guid ProjectId { get; set; }
    public Project Project { get; set; }

    public Guid CityId { get; set; }
    public City City { get; set; }
}

附言

这项工作 - 但代码开销

context.Projects
.Include(x => x.Members) //List<Member>
.Include(x => x.Members.Select(z => z.City)) //City is navigation property
.Select(x => new {
    Project = x,
    Members = x.Members.Select(z => new {
        Item = z,
        City= z.City
    }).ToList(),
    Amount = 22
})
.ToList(); 

【问题讨论】:

  • 这是 EF 6 还是 7?
  • 你能展示你的项目类吗?
  • 添加信息:EntityFramework 6 和部分类
  • 您可以尝试将.Include() 移动到语句的末尾,例如.Include(x =&gt; x.Project.Members).Include(x =&gt; x.Project.Members).Select(z =&gt; z.City)
  • Move or add to end = "查询的结果类型既不是EntityType也不是具有实体元素类型的CollectionType。只能为具有这些结果类型之一的查询指定包含路径。”

标签: c# entity-framework linq


【解决方案1】:

您在包含后执行的任何操作(过滤除外)都会导致包含被丢弃。通过在包含后调用AsEnumerable,您将确保查询被执行,其余操作将在内存中完成:

context.Projects 
       .Include(x => x.Members) 
       .Include(x => x.Members.Select(z => z.City))
       .AsEnumerable() 
       .Select(x => new { Project = x, Amount = 22 }) 
       .ToList(); 

【讨论】:

  • 奇怪的是,我使用的是 EF 6.0,而我的 Include 只接受 Include("Table") 或 nameof(Table)
  • 手动添加一个 using for system.data.entity 然后 lambda 也可用
【解决方案2】:

将您的导航属性声明为虚拟,列表为​​ ICollection,并让 EF 在水合您的实体时替换为它的具体实现:

public class Project
    {
        public Project { 
            Members = new HashSet<ProjectMember>(); 
        }
        public Guid Id { get; set; }
        public string Name { get; set; }
        public virtual ICollection<ProjectMember> Members { get; set; }
    }

    public class ProjectMember
    {
        public Guid ProjectId { get; set; }
        public virtual Project Project { get; set; }

        public Guid CityId { get; set; }
        public virtual City City { get; set; }
    }

【讨论】:

  • 声明为虚拟 - 序列化为 json 的许多问题。我需要在加载时管理哪个属性(包括)
  • 我知道这是一个迟到的评论,但实体几乎不应该被序列化为 JSON。在序列化之前将您需要的属性映射到模型中,以避免可怕的“在实体上找到循环引用...”错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-05
  • 2013-12-18
  • 1970-01-01
  • 2014-09-17
  • 1970-01-01
  • 2011-02-09
  • 2017-10-23
相关资源
最近更新 更多