Entity framework 如何计算关联实体而不在实体框架中获取它们
我一直在想这一点有一段时间了,所以我认为值得使用我的第一篇堆栈溢出帖子来询问它 想象一下,我与一个相关的消息列表进行了讨论:Entity framework 如何计算关联实体而不在实体框架中获取它们,entity-framework,count,Entity Framework,Count,我一直在想这一点有一段时间了,所以我认为值得使用我的第一篇堆栈溢出帖子来询问它 想象一下,我与一个相关的消息列表进行了讨论: DiscussionCategory discussionCategory = _repository.GetDiscussionCategory(id); discussionCategory.Discussions是当前未加载的讨论实体列表 我想要的是能够在discussionCategory中迭代讨论,并在不获取消息数据的情况下说出每个讨论中有多少消息 当我之前尝
DiscussionCategory discussionCategory = _repository.GetDiscussionCategory(id);
discussionCategory.Discussions是当前未加载的讨论实体列表
我想要的是能够在discussionCategory中迭代讨论,并在不获取消息数据的情况下说出每个讨论中有多少消息
当我之前尝试过这一点时,我必须加载讨论和消息,以便我可以这样做:
discussionCategory.Discussions.Attach(Model.Discussions.CreateSourceQuery().Include("Messages").AsEnumerable());
foreach(Discussion discussion in discussionCategory.Discussions)
{
int messageCount = discussion.Messages.Count;
Console.WriteLine(messageCount);
}
对我来说,这似乎效率很低,因为我正在从数据库中提取数百个消息体,并将它们保存在内存中,而我所要做的只是为了表示目的而计算它们的数量
我见过一些涉及这个问题的问题,但它们似乎没有直接解决这个问题
提前感谢您对这个问题的任何想法
更新-根据要求提供更多代码:
public ActionResult Details(int id)
{
Project project = _repository.GetProject(id);
return View(project);
}
然后在视图中(只是为了测试它):
我希望这能让我的问题更清楚一点。如果您需要更多的代码详细信息,请告诉我。我没有直接的答案,但只能指出NHibernate和EF 4.0之间的以下比较,这似乎表明即使在EF 4.0中,也没有现成的支持在不检索集合的情况下获取相关实体集合的计数
我对你的问题投了赞成票并加了星星。希望有人能提出一个可行的解决方案。简单;只需投影到POCO(或匿名)类型: 当您查看生成的SQL时,您将看到,
Count()
是由DB服务器完成的
请注意,这在EF 1和EF 4中都有效。如果您使用的是Entity Framework 4.1或更高版本,则可以使用:
var discussion = _repository.GetDiscussionCategory(id);
// Count how many messages the discussion has
var messageCount = context.Entry(discussion)
.Collection(d => d.Messages)
.Query()
.Count();
来源:我在处理多个映射程序时遇到了相同的问题,包括EF和DevXPress XPO(它甚至不允许单个实体映射到多个表)。我发现最好的解决方案是基本上使用EDMX和T4模板在SQL Server中生成可更新的视图(使用而不是触发器),这样您就可以对SQL进行低级控制,从而可以在select子句中执行子查询,使用各种复杂联接来引入数据等等。如果这不是一次性的,如果您发现自己需要计算许多不同的关联实体,那么数据库视图可能是一个更简单(并且可能更合适)的选择:
CREATE VIEW DiscussionCategoryWithStats AS
SELECT dc.*,
(SELECT count(1) FROM Messages m WHERE m.DiscussionCategoryId = dc.Id)
AS MessageCount
FROM DiscussionCategory dc
(如果您使用的是实体框架代码优先迁移,请参阅关于如何创建视图的部分。)// You'll need to implement this!
DiscussionCategoryWithStats dcs = _repository.GetDiscussionCategoryWithStats(id);
int i = dcs.MessageCount;
...
我知道这是一个老生常谈的问题,但它似乎是一个持续存在的问题,上面的答案都不能提供一个很好的方法来处理列表视图中的SQL聚合 我假设直接的POCO模型和代码首先与模板和示例中的一样。虽然从DBA的角度来看,SQL视图解决方案很不错,但它重新引入了并行维护代码和数据库结构的挑战。对于简单的SQL聚合查询,您不会从视图中看到太多的速度增益。您真正需要避免的是多个(n+1)数据库查询,如上面的示例所示。如果您有5000个父实体,并且正在计算子实体(例如,每个讨论的消息),那么这就是5001个SQL查询 您可以在一个SQL查询中返回所有这些计数。这是怎么做的
System.ComponentModel.DataAnnotations.Schema
命名空间中的[NotMapped]
数据注释向类模型添加占位符属性。这为您提供了一个存储计算数据的位置,而无需向数据库中实际添加列或投影到不必要的视图模型
...
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MyProject.Models
{
public class Discussion
{
[Key]
public int ID { get; set; }
...
[NotMapped]
public int MessageCount { get; set; }
public virtual ICollection<Message> Messages { get; set; }
}
}
DiscussionID
是消息中的FK
)
foreach (var d in discussions)
{
d.MessageCount = (_counts.ContainsKey(d.ID)) ? _counts[d.ID] : 0;
}
return View(discussions);
MessageCount
属性
@foreach (var item in Model) {
...
@item.MessageCount
...
}
@item.Messages.Count
,而不必担心可能会加载大量不需要的对象数据,那当然很好
希望这有帮助。您好,谢谢您的回答。不幸的是,我以前尝试过这个方法,发现匿名类型的count属性在所有讨论中都返回了零。在看到你的答案后,我又尝试了一次这种方法,但结果是一样的。就保持实体与数据存储的“连接”而言,我可能误解了框架的某些内容。其他人能否确认上述方法有效?显示您的代码;你做错了什么。我们在运输应用程序中广泛使用此功能。我怀疑您试图在EF关联属性(如您的问题中)而不是L2E查询(如我的回答中)上执行此操作。那是完全不同的,;前者是对象的LINQ;后者是LINQ到实体
var _counts = db.Messages.GroupBy(m => m.DiscussionID).ToDictionary(d => d.Key, d => d.Count());
foreach (var d in discussions)
{
d.MessageCount = (_counts.ContainsKey(d.ID)) ? _counts[d.ID] : 0;
}
return View(discussions);
@foreach (var item in Model) {
...
@item.MessageCount
...
}