LINQ到实体包括+方法在哪里

问题描述 投票:14回答:2

我有N×N的表,试想:

用户(ID,...)< - UserAddresses(ID,用户id,addressId,启用,...) - >地址(ID,...)

UserAddresses包含FK到用户,解决。对于我所知道的,实体框架用户创建的实体,包含一个集合UserAddresses。该地址包含一个集合UserAddresses,和特定UserAddress包含一个refenrece到用户和一个地址。

现在我想使通过LINQ下一个查询。对于一个特定的用户ID,只能得到与设置好的为true启用标志userAddresses。对于一个特定的用户ID,userAddresses可以包含多个条目,但只有一个设置好的此特定用户。

我能做的查询是:

context.User.Include( x => x.UserAddresses )
            .Include( x => x.UserAddresses.Select(y => y.Address) )
            .Single( x => x.id == USER_ID )

但我真正想要的是不加载所有UserAddresses为该用户设置好的为TRUE ......只有一个包含启用!

有人可以帮我做这个查询?

c# .net linq entity-framework include
2个回答
16
投票

有一个在EF没有办法部分加载关联属性。请尝试选择到一个匿名类型只需要采取什么:

var result = context.User
   .Where(u => u.Id == userId)
   .Select(u => new {
       Addresses = u.UserAddresses.Select(ua => ua.Address)
            .Where(a => a.Enabled),
       User = u // if you need this as well 
   })
   .Single();

这将不加载result.User.UserAddresses,但result.Addresses将有你想要什么。

如果你真的想回到一切为用户类的一部分,你需要分离result.User,然后更新result.User.UserAddresses指向result.Addresses。


1
投票

另一种替代方案是使用Load()Include()代替:

var foundUser = context.User.Single(x => x.Id == USER_ID);

context.Entry(foundUser).Collection(u =>
u.UserAddresses).Query().Where(userAddress =>
userAddress.Enabled).Load();

请记住,Load()方法可以通过EF在某些情况下被忽略:

  1. 如果您正在使用的延迟加载功能一起使用EF,获取你的对象带来了已标记为你的类虚拟所有相关的藏品。所以做context.User.Single( x => x.id == USER_ID );除非你从财产User类去除Virtual关键字关闭延迟加载你的收藏,你会得到与用户相关联的所有UserAddresses。
  2. 如果要添加在你的程序/删除UserAddresses采集和调用context.SaveChanges();没有当加载用户物体配置的情况下,接下来的时间,UserAddresses收集从不会从DB(最新的更改)EF上下文高速缓存加载。在这种情况下,你需要配置您的上下文并从上下文菜单让用户之前实例化一个新的上下文。例如,如果您有您的UserAddresses收集5个项目的用户,并且使禁用的项目(item.Enabled = false)中的一个,然后调用context.SaveChanges()没有下一次配置你的情况下,当您从同一场景中获得用户对象,它已经拥有5其收藏它来自上下文高速缓存而忽略你的Load()方法中的项目。

PS:

延迟加载功能打开,如果采用以下所有条件:

  1. context.Configuration.LazyLoadingEnabled = TRUE;
  2. context.Configuration.ProxyCreationEnabled = TRUE;
  3. UserAddresses已在User类中定义的虚拟。
© www.soinside.com 2019 - 2024. All rights reserved.