2

假設我有以下的聚合根:尋呼實體(的集合體)

public class Aggregate 
{ 
    public int Id {get; set;} 

    public List<Entity> Entities {get; set;} 
} 

而下面的庫:

public class AggregateRepository 
{ 
    public Aggregate GetPaged(int Id) 
    { 
    return db.Aggregate 
       .Include(x=>x.Entities) 
       .Find(id)    
    } 
} 

問題:怎麼能我得到一個分頁和排序的實體列表?哪些是最好的方法來獲得實體分頁和排序,但也與綜合信息?

編輯:

什麼是你考慮以下的方法呢?

public class AggregateRepository 
    { 
     public IEnumerable<Entity> GetEntitiesPaged(int id) 
     { 
     return db.Aggregate 
        .Include(x=>x.Aggregate) 
        .Where(x=>x.Id = id) 
        .Select(x=>x.Entities) 
        .Take(20);   
     } 
    } 

而不是返回一個聚集對象,我可以收到一個包含聚合對象的實體列表(在這種情況下是20個實體)。在DDD模式下處理聚合是否是一種好方法?

+0

爲了給你一個有用的答案,我想知道你正在嘗試實現分頁和排序的實體列表。 - 您需要在您的寫入或讀取模型中使用分頁和排序的實體列表嗎? - 您打算使用此頁面向用戶顯示實體嗎? - 您是否要逐頁閱讀(查詢)實體以強制您的域中的某些不變量? –

回答

1

簡短的回答是,你應該避免查詢你的域模型。

相反,如果需要,可以使用帶有讀取模型的專用查詢圖層;否則更原始的東西,如DataRow

更新

你應該儘量不要查詢時創建的聚集。這意味着不訪問存儲庫。查詢層看起來像這樣:

public interface ISomethingQuery 
{ 
    IEnumerable<SomethingDto> GetPage(SearchSPecification specification, int pageNumber); 
    // -or- 
    IEnumerable<DataRow> GetPage(SearchSPecification specification, int pageNumber); 
} 

然後,您將使用此查詢接口的實現來獲取所需的數據以進行顯示/報告。

+0

感謝您的回答:)當你說:「使用一個專門的查詢層與一個讀取模型」,你是否要求在獲取內存中的所有數據之後這樣做(在調用GetPaged()方法之後),對不對?這樣,如果我的實體有很多數據,性能會下降,我想避免這種情況。 DataRow選項現在不是一種選擇,因爲我將不得不改變應用程序方法,而且我不想這樣做。 我編輯了我的帖子。如果你想評論我欣賞:) – ASantos

+0

我已經更新了答案,以闡明這件事:) –

1

首先,您應該將您的寫入端(命令)與讀取端(查詢)分開,它們的名稱爲CQRS。你可以看看example

但是,如果您只是想獲得分頁和排序的實體列表,您可以使用以下方法。

public ICollection<Aggregate> GetSortedAggregates(AggregateListFilter filter, out int rowCount) 
{ 
    var query = (base.Repository.CurrentSession() as ISession).QueryOver<Aggregate>(); 

    query = query.And(q => q.Status != StatusType.Deleted); 

    if (!string.IsNullOrWhiteSpace(filter.Name)) 
     query = query.And(q => q.Name == filter.Name); 

    rowCount = query.RowCount(); 

    switch (filter.OrderColumnName) 
    { 
     case ".Name": 
      query = filter.OrderDirection == OrderByDirections.Ascending ? query.OrderBy(x => x.Name).Asc : query.OrderBy(x => x.Name).Desc; 
      break; 
     default: 
      query = filter.OrderDirection == OrderByDirections.Ascending ? query.OrderBy(x => x.Id).Asc : query.OrderBy(x => x.Id).Desc; 
      break; 
    } 

    if (filter.CurrentPageIndex > 0) 
    { 
     return query 
     .Skip((filter.CurrentPageIndex - 1) * filter.PageSize) 
     .Take(filter.PageSize) 
     .List(); 
    } 

    return query.List(); 
}