关于C#:LINQ表达式语法如何与Include()配合使用以进行快速加载

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;


如果您想要的是一个查询,该查询将通过Action.UserId外键属性返回其关联的User实体实际上存在的所有Action实体,则可以这样做:

1
2
3
4
5
var results = context.Actions
    .Include("User")
    .Where(action =>
        context.Users.Any(user =>
            user.UserId == action.UserId));

但是,您不必使用外键属性来进行过滤,因为您还具有导航属性。因此,可以通过过滤Action.User导航属性来简化查询,如下例所示:

1
2
3
var results = context.Actions
    .Include("User")
    .Where(action => action.User != null);

如果您的模型指出Action.User属性永远不能为空(即Action.UserId外键在数据库中不能为空),并且您想要的实际上是所有Action实体及其关联的Users,则查询变得更简单

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。这对我有用:-)