C# EF Lambda包含导航属性
我有以下对象,称为Filter,具有以下属性:C# EF Lambda包含导航属性,c#,entity-framework,linq,lambda,C#,Entity Framework,Linq,Lambda,我有以下对象,称为Filter,具有以下属性: public int Id { get; set; } public string Name { get; set; } public virtual ICollection<Type> Types{ get; set; } public virtual ICollection<Step> Steps { get; set; } public virtual ICollection&
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Type> Types{ get; set; }
public virtual ICollection<Step> Steps { get; set; }
public virtual ICollection<Flow> Flows { get; set; }
public virtual ICollection<Room> Rooms { get; set; }
public int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection类型{get;set;}
公共虚拟ICollection步骤{get;set;}
公共虚拟ICollection流{get;set;}
公共虚拟ICollection房间{get;set;}
当我从数据库中选择过滤器列表时,我不知道如何包含集合(类型、步骤、流、房间)。我的代码如下:
var filters = (
from filter in dbContext.DbSet<Filter>()
let rooms = (
from r in dbContext.DbSet<Room>()
select r
)
let eventTypes = (
from t in dbContext.DbSet<Type>()
select t
)
let processFlows = (
from f in dbContext.DbSet<Flow>()
select f
)
let processFlowSteps = (
from s in dbContext.DbSet<Step>()
select s
)
select filter
).ToList();
var过滤器=(
来自dbContext.DbSet()中的筛选器
出租房间=(
来自dbContext.DbSet()中的r
选择r
)
让eventTypes=(
来自dbContext.DbSet()中的t
选择t
)
让processFlows=(
来自dbContext.DbSet()中的f
选择f
)
让processFlowSteps=(
来自dbContext.DbSet()中的
选择s
)
选择过滤器
).ToList();
我的筛选器集合已返回,但其中的集合为空。你能告诉我怎样才能做到这一点吗
Ps:由于性能问题,我不想使用Include,我不喜欢Entity Framework生成查询的方式,我希望这样做。您需要使用扩展方法:
var filters=dbContext.DbSet<Filter>()
.Include(f=>f.Types)
.Include(f=>f.Steps)
.Include(f=>f.Flows)
.Include(f=>f.Rooms)
.ToList()
您需要使用扩展方法:
var filters=dbContext.DbSet<Filter>()
.Include(f=>f.Types)
.Include(f=>f.Steps)
.Include(f=>f.Flows)
.Include(f=>f.Rooms)
.ToList()
你的方法行得通,你只是做错了 要包含导航属性,只需执行一个子选择(使用linq),例如:
var filters = (from filter in dbContext.DbSet<Filter>()
select new Filter
{
filter.Id,
filter.Name,
Rooms = (from r in dbContext.DbSet<Room>()
where r.FilterId == filter.Id
select r).ToList()
}).ToList();
var filters=(来自dbContext.DbSet()中的过滤器)
选择新过滤器
{
filter.Id,
filter.Name,
Rooms=(来自dbContext.DbSet()中的r)
其中r.FilterId==filter.Id
选择r.ToList()
}).ToList();
请记住,在调用返回方法(ToList、Any、FirstOrDefault等)之前,EF不会执行查询。这样,它就不会通过不使用Include()来执行那些丑陋的查询,而是简单地触发两个查询并正确地分配所需对象中的值。您的方法可以正常工作,但您的操作是错误的 要包含导航属性,只需执行一个子选择(使用linq),例如:
var filters = (from filter in dbContext.DbSet<Filter>()
select new Filter
{
filter.Id,
filter.Name,
Rooms = (from r in dbContext.DbSet<Room>()
where r.FilterId == filter.Id
select r).ToList()
}).ToList();
var filters=(来自dbContext.DbSet()中的过滤器)
选择新过滤器
{
filter.Id,
filter.Name,
Rooms=(来自dbContext.DbSet()中的r)
其中r.FilterId==filter.Id
选择r.ToList()
}).ToList();
请记住,在调用返回方法(ToList、Any、FirstOrDefault等)之前,EF不会执行查询。这样,它就不会通过不使用Include()来执行那些丑陋的查询,而只需启动两个查询并正确分配所需对象中的值。您可以使用延迟加载,如何: 您首先需要获取属性,这些属性是虚拟的,然后是受保护的访问类型的空构造函数,才能很好地完成工作
public virtual ICollection<Type> Types{ get; set; }
public virtual ICollection<Step> Steps { get; set; }
public virtual ICollection<Flow> Flows { get; set; }
public virtual ICollection<Room> Rooms { get; set; }
我认为此解决方案将解决您的问题。您可以使用延迟加载,如何: 您首先需要获取属性,这些属性是虚拟的,然后是受保护的访问类型的空构造函数,才能很好地完成工作
public virtual ICollection<Type> Types{ get; set; }
public virtual ICollection<Step> Steps { get; set; }
public virtual ICollection<Flow> Flows { get; set; }
public virtual ICollection<Room> Rooms { get; set; }
我认为这个解决方案可以解决你的问题。为什么不使用
dbContext.Filters
而不是dbContext.DbSet()
?@juharr这实际上是一回事,所以没关系。“我不喜欢实体框架如何生成查询,我想这样做”你说的“这种方式”是什么意思?如果你指的是显示的代码,显然它不起作用,因此绝对不能是“方式”。即使在select
中包含let
变量(例如select new{filter,rooms,etc…}
),结果查询也会比包含include
的查询糟糕得多,因为let
查询将针对filter
表的每条记录执行。结果集是完全笛卡尔积。听起来像XY的问题。只是加载每个导航一个接一个,我不知道你为什么需要让。您可以具体化过滤器,然后对每个集合执行相同的操作,但这次不需要存储结果。过滤器应该被填充。使用延迟加载时,您不需要被包含。为什么不使用dbContext.filters
而不是dbContext.DbSet()
?@juharr这实际上是一回事,所以没关系。“我不喜欢实体框架如何生成查询,我想这样做”你的意思是什么“这种方式”?如果你指的是显示的代码,显然它不起作用,因此肯定不能是“这种方式”。即使你在选择中包含让变量(例如选择新的{filter,rooms,etc…}
),生成的查询将比使用Include
的查询糟糕得多,因为let
查询将针对Filter
表的每条记录执行。结果集将是完全笛卡尔积。听起来像是XY问题。只需逐个加载每个导航,我不确定您为什么需要let。您可以直接匹配对过滤器进行rialize,然后对每个集合执行相同的操作,但这次您不需要存储结果。应该填充过滤器。由于延迟加载,您不需要被包含。我错误地投了反对票,我真的很抱歉。这是一个让人筋疲力尽的周。由于性能问题,我不想使用包含,我不喜欢实体框架工作的方式k生成查询,我想这样做