DDD,EF,聚合

时间:2011-08-23 10:31:57

标签: c# entity-framework design-patterns domain-driven-design

我正在尝试使用DDD和EF 4.1 Code First。 我有一个Aggregate Root BlogEntry看起来很像这个:

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, ...
}

不幸的是,Entity Framework在这里做的是执行一个查询来获取BlogEntry对象,之后它为每个BlogEntry执行一个查询以检索注释的数量。

- &GT; 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 个答案:

答案 0 :(得分:2)

我会选择更简单,更肯定更有效的方法 - 只需将NumberOfComments添加为BlogEntry上的属性,将其与每个注释一起递增并保留它。仅仅基于聚合有责任保持数据一致的事实。考虑到仅显示数据的请求数量与实际更新数量之间的关系,我认为没有理由在每次有人想看到它时计算这个数字。

答案 1 :(得分: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();