Entity Framework 6.1.3:投影——直接加载children的children
Entity Framework 6.1.3: Projection - load children of children directly
我的 objective 是只访问数据库一次,并使用过滤后的子集合获取订单。
为此,我使用了投影:
using (var db = new context())
{
var query = from o in db.Orders
select
new
{
Order = o,
Events = o.Events.Where(
e => e.SomeBool
&& e.SomeBool2
),
EventsGroups = o.Events.Where(
e => e.SomeBool
&& e.SomeBool2
).Select(e => e.Groups),
};
}
这里的问题是事件中的子集合 "Groups" 未加载。为了解决这个问题,我在查询中将其作为另一个 属性 "EventsGroups" 加载,然后我可以将其与事件放在一起。
我的问题: 有没有办法直接将子 "Groups" 加载到 "Event" 上,这样我就不必将它们作为另一个 属性?
按照
Events = o.Events.Where(
e => e.SomeBool
&& e.SomeBool2
).Include(e => e.Groups), //this cannot be done this way
为什么我要使用投影而不是急于加载:
https://msdn.microsoft.com/en-us/magazine/hh205756.aspx
Filtering include items in LINQ and Entity Framework
标的类:
public class Order
{
public Order()
{
Events = new HashSet<Event>();
}
public int Id { get; set; }
public virtual ICollection<Event> Events { get; set; }
}
public class Event
{
public Event()
{
Groups = new HashSet<Group>();
}
public int Id { get; set; }
public bool SomeBool { get; set; }
public bool SomeBool2 { get; set; }
public virtual ICollection<Group> Groups { get; set; }
}
public class Group
{
public Group()
{
Events = new HashSet<Event>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Event> Events { get; set; }
}
由于 Include
不能与匿名投影相结合,您需要像投影 Order.Events
一样投影 Event.Groups
,即使用另一种匿名类型投影:
var query = from o in db.Orders
select new
{
Order = o,
Events = (from e in o.Events
where e.SomeBool && e.SomeBool2
select new
{
Event = e,
Groups = e.Groups,
}),
};
您可以通过设置 Configuration.LazyLoadingEnabled = true;
来加载所有内容,而不需要任何 Include ,当然...必须牢记性能...取决于...
public MyDatabaseContext(string databaseName)
: base(databaseName)
{
Configuration.LazyLoadingEnabled = true;
}
我相信这对你有用:
using (var db = new context())
{
var query = db.Orders
.Include(o=>o.Events)
.Include(o=>o.Events.Select(e=>e.Groups))
.Select(o=>new
{
Order = o,
Events = o.Events.Where(e => e.SomeBool && e.SomeBool2)
});
}
如果没有,这将:
using (var db = new context())
{
var query = db.Orders
.Include(o=>o.Events)
.Include(o=>o.Events.Select(e=>e.Groups))
.Select(o=>new Order
{
Id=o.Id,
Events = o.Events.Where(e => e.SomeBool && e.SomeBool2).ToList()
});
}
我的 objective 是只访问数据库一次,并使用过滤后的子集合获取订单。
为此,我使用了投影:
using (var db = new context())
{
var query = from o in db.Orders
select
new
{
Order = o,
Events = o.Events.Where(
e => e.SomeBool
&& e.SomeBool2
),
EventsGroups = o.Events.Where(
e => e.SomeBool
&& e.SomeBool2
).Select(e => e.Groups),
};
}
这里的问题是事件中的子集合 "Groups" 未加载。为了解决这个问题,我在查询中将其作为另一个 属性 "EventsGroups" 加载,然后我可以将其与事件放在一起。
我的问题: 有没有办法直接将子 "Groups" 加载到 "Event" 上,这样我就不必将它们作为另一个 属性?
按照
Events = o.Events.Where(
e => e.SomeBool
&& e.SomeBool2
).Include(e => e.Groups), //this cannot be done this way
为什么我要使用投影而不是急于加载:
https://msdn.microsoft.com/en-us/magazine/hh205756.aspx
Filtering include items in LINQ and Entity Framework
标的类:
public class Order
{
public Order()
{
Events = new HashSet<Event>();
}
public int Id { get; set; }
public virtual ICollection<Event> Events { get; set; }
}
public class Event
{
public Event()
{
Groups = new HashSet<Group>();
}
public int Id { get; set; }
public bool SomeBool { get; set; }
public bool SomeBool2 { get; set; }
public virtual ICollection<Group> Groups { get; set; }
}
public class Group
{
public Group()
{
Events = new HashSet<Event>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Event> Events { get; set; }
}
由于 Include
不能与匿名投影相结合,您需要像投影 Order.Events
一样投影 Event.Groups
,即使用另一种匿名类型投影:
var query = from o in db.Orders
select new
{
Order = o,
Events = (from e in o.Events
where e.SomeBool && e.SomeBool2
select new
{
Event = e,
Groups = e.Groups,
}),
};
您可以通过设置 Configuration.LazyLoadingEnabled = true;
来加载所有内容,而不需要任何 Include ,当然...必须牢记性能...取决于...
public MyDatabaseContext(string databaseName)
: base(databaseName)
{
Configuration.LazyLoadingEnabled = true;
}
我相信这对你有用:
using (var db = new context())
{
var query = db.Orders
.Include(o=>o.Events)
.Include(o=>o.Events.Select(e=>e.Groups))
.Select(o=>new
{
Order = o,
Events = o.Events.Where(e => e.SomeBool && e.SomeBool2)
});
}
如果没有,这将:
using (var db = new context())
{
var query = db.Orders
.Include(o=>o.Events)
.Include(o=>o.Events.Select(e=>e.Groups))
.Select(o=>new Order
{
Id=o.Id,
Events = o.Events.Where(e => e.SomeBool && e.SomeBool2).ToList()
});
}