2

尝试执行单个数据库调用来获取实体以及相关子实体的数量。EF6在单个呼叫中计数

我知道我可以检索使用

var count = Context.MyChildEntitySet.Where(....).Count(); 

甚至MyEntity.ListNavigationProperty.Count()

计数,但这就意味着首先得到的实体,紧接着又调用,以获取计数或者使用一个可以检索整个相关实体列表的Include。

我想知道是否有可能在SQL Server中添加一个“计算”列以返回另一个表中相关行的计数?

如果不是我如何要求EF在一次调用中检索每个实体的相关计数?

我想可能使用Join与GroupBy,但这似乎是一个丑陋的解决方案/破解。

public class MyEntity 
{ 
    public uint NumberOfVotes{ get; private set; } 
} 

在理想情况下woudl生成SQL类似于:

SELECT 
    *, 
    (SELECT Count(*) FROM ChildTable c WHERE c.ParentId = p.Id) NumberOfVotes 
FROM ParentTable p 

回答

1

修订

你总是可以下降到下列方式使用实际的SQL ...

string query = "SELECT *, 
         (SELECT Count(*) FROM ChildTable c 
         WHERE c.ParentId = p.Id) as NumberOfVotes 
       FROM ParentTable p"; 

RowShape[] rows = ctx.Database.SqlQuery<RowShape>(query, new object[] { }).ToArray(); 

我意识到这并不理想,因为那时你正在服用依赖于目标数据库的SQL方言。如果您将SQL Server移到其他位置,那么您需要检查并修改字符串。

RowShape类是使用与ParentTable匹配的属性以及名为NumberOfVotes的具有计算的计数的额外属性定义的。

尽管如此,一种可能的解决方法。

+0

选择Coun(*)SQL将通过简单的context.Table.Count()创建。但它确实意味着2次调用我试图避免的数据库。 – 2015-02-18 22:50:37

+0

此刻,创建一个聚集索引视图看起来像是最好的选择:/ – 2015-02-18 23:07:03

+0

上面的代码只会进行一次SQL调用。 – 2015-02-19 00:31:47