考虑以下实体:
public class Principal
{
[Key,DatabaseGenerated]
public int ID{ get; set; }
[Key,DatabaseGenerated]
public virtual ICollection<Dependent> Dependents { get; set; }
}
public class Dependent
{
[Key]
public int PrincipalID { get; set; }
[ForeignKey("PrincipalID")]
public virtual Principal Principal { get; set; }
}
在以下情形中:
var principal = db.Principals.First();
if( principal.Dependents.Any()){
// Do stuff
}
对.Any的调用是否会检索依赖实体,或者EF是否足够聪明,可以在商店中执行Exists而不是检索相关记录并对可枚举执行.Any()?
答案 0 :(得分:1)
实际上没有办法可以发生。
Dependents
是ICollection<T>
,而不是IQueryable<T>
,因此Any()
是标准的LINQ到对象Any()
。
EF会在你第一次获得财产后立即加载所有对象。
答案 1 :(得分:1)
它将检索所有依赖实体。
该属性为ICollection
,表示它实现IEnumerable
而不是IQueryable
。这意味着Any
只是在内存中迭代集合(意味着它需要延迟加载),而不是向查询提供程序发送Expression
,让查询提供程序使用{{{}执行任何所需的操作。 1}}。
答案 2 :(得分:1)
由于Dependents
导航属性不是IQueryable
(并且EF在导航属性上不支持IQueryable
),因此一旦加载,整个导航属性数据执行并具体化,并使用Enumerable.Any
(Linq-to-Objects)调用进一步的LINQ调用。
答案 3 :(得分:1)
如果您想在数据库上执行 的操作,可以执行以下操作:
if (db.Principals.Take(1).Any(p => p.Dependents.Any()))
{
// do stuff
}
或者假设您只想使用Principal
来对第一个Dependent
执行某些操作:
var principal =
db.Principals.Take(1)
.Where(p => p.Dependents.Any()))
.SingleOrDefault();
if (principal != null)
{
// do stuff with principal...
}