使用实体框架(EF)在存储库中分配实体(聚合)

时间:2017-07-12 10:33:47

标签: c# entity-framework domain-driven-design repository-pattern

假设我有以下聚合根:

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模式的聚合是一种好方法吗?

2 个答案:

答案 0 :(得分:1)

简短的回答是,您应该避免查询域模型。

如果需要,请使用带有读取模型的专用查询层;还有更原始的东西,比如DataRow

<强> 更新

查询时应该尽量不创建聚合。这意味着不访问存储库。查询图层看起来像这样:

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

然后,您将使用此查询界面的实现来获取显示/报告所需的数据。

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