How does LINQ expression syntax work with Include() for eager loading
我在下面有一个查询,但是我想执行一个Include()以渴望加载属性。 动作具有导航属性用户(Action.User)
1)我的基本查询:
1 2 3 | from a in Actions join u in Users on a.UserId equals u.UserId select a |
2)第一次尝试:
1 2 3 | from a in Actions.Include("User") join u in Users on a.UserId equals u.UserId select a |
但是没有填充Action.User。
3)尝试急于在查询之外的操作中将"用户"加载到导航属性中:
1 2 3 | (from a in Actions join u in Users on a.UserId equals u.UserId select a).Include("User") |
在LINQPad中尝试包括的我得到一个错误:
'System.Linq.IQueryable'不包含'Include'的定义,并且找不到扩展方法'Include'接受类型为'System.Linq.IQueryable'的第一个参数(按F4键以添加using指令或程序集引用 )
我认为这是因为LINQ不支持Include()。
所以我在VS中尝试过; 查询2运行,但返回未填充的User属性。
查询3扩展方法似乎不存在,尽管在没有查询的情况下它确实存在于Action本身。
我想通了,还是谢谢你的建议。
解决方案是执行此操作(我的问题中的第二次尝试):
1 2 3 | var qry = (from a in Actions join u in Users on a.UserId equals u.UserId select a).Include("User") |
查询后intellisense不显示Include的原因是因为我需要使用以下命令:
1 | using System.Data.Entity; |
这样做一切正常。
更好的重构友好代码(EF6)
1 2 3 4 5 | using System.Data.Entity; [...] var x = (from cart in context.ShoppingCarts where table.id == 123 select cart).Include(t => t.CartItems); |
要么
1 2 3 | var x = from cart in context.ShoppingCarts.Include(nameof(ShoppingCart.CartItems)) where table.id == 123 select cart; |
更新3/31/2017
您还可以对两种方法使用lambda语法中的include:
1 2 3 | var x = from cart in context.ShoppingCarts.Include(p => p.ShoppingCart.CartItems)) where table.id == 123 select cart; |
如果您想要的是一个查询,该查询将通过
1 2 3 4 5 | var results = context.Actions .Include("User") .Where(action => context.Users.Any(user => user.UserId == action.UserId)); |
但是,您不必使用外键属性来进行过滤,因为您还具有导航属性。因此,可以通过过滤
1 2 3 | var results = context.Actions .Include("User") .Where(action => action.User != null); |
如果您的模型指出
1 | var results = context.Actions.Include("User"); |
进行发布的问题中提到的基本查询,除非返回以下匿名类型,否则您将看不到用户属性:
1 2 3 4 5 6 7 8 9 10 | from a in Actions join u in Users on a.UserId equals u.UserId select new { actionUserId = a.UserId . . . userProperty1 = u.UserId }; |
但是,要在ObjectContext上使用Include方法,可以使用以下方法:
使用以下行来确保已关闭LazyLoading:
1 | entities.ContextOptions.LazyLoadingEnabled = false; |
然后继续
1 2 3 | var bar = entities.Actions.Include("User"); var foo = (from a in bar select a); |
为此,我使用LoadWith选项
1 2 3 | var dataOptions = new System.Data.Linq.DataLoadOptions(); dataOptions.LoadWith<Action>(ac => as.User); ctx.LoadOptions = dataOptions; |
而已。 ctx是您的DataContext。这对我有用:-)