【问题标题】:DDD, EF, AggregationsDDD、EF、聚合
【发布时间】:2011-08-23 10:31:57
【问题描述】:

我正在尝试使用 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 个博客条目的标题以及这些博客条目的 cmets 数量。

目前的实现方式与此类似:

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

不幸的是,Entity Framework 在这里所做的是执行一个查询以获取 BlogEntry 对象,然后为每个 BlogEntry 执行一个查询以检索 cmets 的数量。

-> 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

谢谢。

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      你可以这样做,但它会创建匿名类型,

       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();
      

      【讨论】:

      • 我知道这一点,但这如何适合 ddd 环境。存储库不应该返回实体 - 不是匿名类型吗?
      • @bes:如果您的域对象上有一个非持久的 CommentCount 属性,您可以让您的存储库使用 Jayantha 建议的查询填充该属性,并返回一个实体。
      猜你喜欢
      • 1970-01-01
      • 2017-05-25
      • 2016-03-21
      • 2011-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多