我很确定我只是愚蠢得可笑,但我似乎无法弄清楚......
我首先在 EF6 代码中有以下对象:
public class Vessel
{
public int Id {get;set;}
public string Name {get;set;}
public virtual ICollection<Position> Positions {get;set;}
}
public class Position
{
public int Id {get;set;}
public double Lat {get;set;}
public double Lon {get;set;}
public virtual Vessel Vessel {get;set;}
}
我正在执行以下操作:
var vess = context.Vessels.First();
if (vess.Positions.Any())
{
// Do something spiffy
}
我正在 Rhinos 中对此进行分析,并生成以下 SQL:
SELECT [Extent1].[Id] AS [Id],
[Extent1].[VesselId] AS [VesselId],
[Extent1].[Lat] AS [Lat],
[Extent1].[Lon] AS [Lon]
FROM [dbo].[Position] AS [Extent1]
WHERE [Extent1].[VesselId] = 1 /* @EntityKeyValue1 */
我的问题是,为什么?我不妨这样写:
if (vess.Positions.Count() > 0)
就像我说的,我确信我只是愚蠢。
最佳答案
自 Positions
定义为ICollection<Position>
,编译器正在绑定(bind)Any
到Enumerable
(Linq-to-objects)扩展方法,仅检查集合中是否存在项目。通过这样做,它调用了虚拟Positions
的getter。属性已被 EF 覆盖,通过生成您看到的 SQL 来加载集合的完整内容。
I might as well have written
if (vess.Positions.Count() > 0)
不,出于同样的原因,这会做同样的事情。
如果这确实是一个问题,并且不是您所期望的,那么您必须构建等效的 EF 查询:
var positions = context.Positions
.Where(p => p.VesselId == vess.Id);
if (positions.Any())
{
// Do something spiffy
}
但如果“一些漂亮的事情”需要用 Positions
做一些事情,我不会这么认为。属性内容,您不妨将其加载到 if
中就像您现在所做的那样。
关于c# - Entity Framework .Any()正在返回完整的表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41467414/