我有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 ......只有一个包含启用!
有人可以帮我做这个查询?
有一个在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。
另一种替代方案是使用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在某些情况下被忽略:
context.User.Single( x => x.id == USER_ID );
除非你从财产User类去除Virtual
关键字关闭延迟加载你的收藏,你会得到与用户相关联的所有UserAddresses。item.Enabled = false
)中的一个,然后调用context.SaveChanges()
没有下一次配置你的情况下,当您从同一场景中获得用户对象,它已经拥有5其收藏它来自上下文高速缓存而忽略你的Load()
方法中的项目。PS:
延迟加载功能打开,如果采用以下所有条件: