【问题标题】:Paging Entities (of Aggregates) in Repository with Entity Framework (EF)使用实体框架 (EF) 对存储库中的(聚合的)实体进行分页
【发布时间】:2017-07-12 10:33:47
【问题描述】:

假设我有以下聚合根:

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

【问题讨论】:

  • 为了给你一个有用的答案,我想知道你想通过分页和排序的实体列表来实现什么。 - 您的写入或读取模型中是否需要分页和排序的实体列表? - 您打算使用此页面向用户显示实体吗? - 您是否要逐页阅读(查询)实体以在您的域中强制执行一些不变量?

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


【解决方案1】:

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

如果需要,不如使用带有读取模型的专用查询层;其他更原始的东西,例如DataRow

更新

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

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

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

【讨论】:

  • 感谢您的回答 :) 当您说:“使用带有读取模型的专用查询层”时,您是说在获取内存中的所有数据之后(在调用 GetPaged () 方法),对吗?这样,如果我的实体有很多数据,性能会下降,我想避免这种情况。 DataRow 选项目前不是一个选项,因为我将不得不更改应用程序方法并且我不想这样做。我编辑了我的帖子。如果您想发表评论,我很感激:)
  • 我已经更新了答案以更清楚地说明此事:)
【解决方案2】:

首先,您应该将写入端(命令)与读取端(查询)分开,这称为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();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多