使用ToList()

时间:2015-12-03 13:56:06

标签: c# entity-framework count

使用C#Entity Framework v6.1.1,我试图在DbSet上进行Count操作:

//Items is a List<Item>
int count = db.MyObjects.Count(o => o.Items.FirstOrDefault(i => i.ItemID == 1) != default(Item));

我没有使用Contains,因为在使用Where Count等时存在已知的EF问题。

现在,上面的行抛出一个NullReferenceException,告诉我对象引用没有设置为object的实例。

将其更改为:

//Items is a List<Item>
int count = db.MyObjects.ToList().Count(o => o.Items.FirstOrDefault(i => i.ItemID == 1) != default(Item));

按预期工作。

现在,我的假设是DbSet作为代理类型工作,仅在请求时加载延迟对象,ToList()迫使其加载。

我担心这一切的表现。是否有更好的方法来计算DbSet?我是否真的强制要在所有地方进行ToList()通话?

我注意到DbSet IEnumerable

更新:我忘了提到我禁用了延迟加载,并且我在没有将预先加载应用到Items集合的情况下调用此代码,这可能解释了很多。

1 个答案:

答案 0 :(得分:1)

您似乎遇到了实现问题,但要回答您的标题问题,我认为

int count = db.MyObjects
    .Where(x => x.Items.Any(y => y.ItemID == 1))
    .Count();

应该

进行调查:

Folders.Where(x => x.Files.Any(y => y.IdPseudoCountry == 16)).Count()
Folders.Count(x => x.Files.Any(y => y.IdPseudoCountry == 16))

导致:

SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
    COUNT(1) AS [A1]
    FROM [dbo].[tableD] AS [Extent1]
    WHERE  EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[tableF] AS [Extent2]
        WHERE ([Extent1].[idDossier] = [Extent2].[idDossier]) AND (16 = [Extent2].[idPays])
    )
)  AS [GroupBy1]

Folders.Count(x => x.Files.FirstOrDefault(y => y.IdPseudoCountry == 16) != default(File))

导致:

SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
    COUNT(1) AS [A1]
    FROM ( SELECT 
        [Extent1].[idDossier] AS [idDossier], 
        (SELECT TOP (1) 
            [Extent2].[idFichier] AS [idFichier]
            FROM [dbo].[tableF] AS [Extent2]
            WHERE ([Extent1].[idDossier] = [Extent2].[idDossier]) AND (16 = [Extent2].[idPays])) AS [C1]
        FROM [dbo].[tableD] AS [Extent1]
    )  AS [Project2]
    WHERE [Project2].[C1] IS NOT NULL
)  AS [GroupBy1]

但在我的情况下,我在任何情况下都不例外。