3

我正在试验DDD和EF 4.1 Code First。 我有一个聚合根BlogEntry看起来simlar这样:DDD,EF,Aggregations

public class BlogEntry 
{ 
    public long Id { get; set; } 
    public string Title { get; set;} 
    public string Content { get; set; } 
    public DateTime Created { get; set; } 

    public virtual ICollection<BlogEntryComment> Comments { get; set; } 
} 

现在,我想显示最新10篇博客文章的标题和评论在一个门户网站,这些博客文章的数量。

目前这是实现与此类似:

foreach(BlogEntry be in blogEntryRepository.GetLatestBlogEntries()) 
{ 
    string title = be.Title; 
    int amountOfComments = be.Comments.Count(); 
    // display title, amountOfComments, ... 
} 

可惜的是什么实体框架在这里所做的是执行一个查询来获取BlogEntry对象之后,它执行一个查询每个BlogEntry检索的数注释。

- > EF生成的SQL与此类似:

select top 10 * from BlogEntry order by Created desc 

,然后10倍:

select count(*) from BlogEntryComment where BlogEntry = @blogEntryId 

如何防止在某种程度上这种行为没有预先加载的所有意见,但仍然没有根据数据库为每个BlogEntry拍摄查询 - 但不会与任何DDD规则相冲突?

(我想什么EF火灾对数据库是这样的:)

select top 10 
be.*, 
(select count(*) from BlogEntryComment c where c.BlogEntryId = be.Id) as AmountOfComments 
from BlogEntry be order by be.Created DESC 

感谢。

回答

2

我会选择简单,肯定更有效的方式 - 只需添加NumberOfComments财产上BlogEntry,每评论增加它,坚持它。只是基于聚合负责保持数据一致的事实。考虑到只显示数据的请求数量与实际更新数量之间的关系,我认为每次有人想要查看时都没有理由对此数字进行计数。

0

你能做到这样,但它会创建匿名类型,

var p= from a in db.BlogEntries 
     select new {a, a.Comments.Count}; 
     var k = p.ToList(); 

编辑 .. 你可以像这样,

禁用延迟加载, 评论数属性添加到blogEntry域类

public class BlogEntry 
     { 
      public int commentCount{ 
      get 
      { 
      if(this.comments==null){ 
       return this._commentCount 
      }else{ 
       return this.Comments.count; 

      } 
      } 
      set{ 
       this._commentCount=value; 
      } 


     } 
     //other properties... 

     } 

将新方法添加到您的存储库以获取所有评论数,

var p= from a in db.BlogEntries 
     select new BlogEntry{Id=a.Id,CommentCount= a.Comments.Count , ect..}; 
     var k = p.ToList(); 
+0

我意识到这一点,但如何适应ddd环境。 不是应该返回实体的存储库 - 不是匿名类型? – bes

+1

@bes:如果你的域对象上有一个非持久的'CommentCount'属性,你可以让你的存储库用类似Jayantha建议的查询填充该属性,并返回一个实体。 –

+0

我已经添加了一些解决方法 –