ДДД, ЭФ, Агрегации - PullRequest
       32

ДДД, ЭФ, Агрегации

3 голосов
/ 23 августа 2011

Я экспериментирую с 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 для получения количества комментариев.

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

2 голосов
/ 23 августа 2011

Я бы выбрал более простой и, безусловно, более эффективный способ - просто добавьте NumberOfComments как свойство в BlogEntry, увеличивайте его с каждым комментарием и сохраняйте его. Просто опирайтесь на тот факт, что агрегат несет ответственность за поддержание согласованности данных. Принимая во внимание количество запросов на отображение только данных и количество фактических обновлений, я не вижу смысла подсчитывать это число каждый раз, когда кто-то хочет его увидеть.

0 голосов
/ 23 августа 2011

вы можете сделать так, но это создаст анонимный тип,

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