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

C# 使用实体框架(EF)在存储库中分页实体(聚合),c#,entity-framework,domain-driven-design,repository-pattern,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 IEnumera

假设我有以下聚合根:

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

    public List<Entity> Entities {get; set;}
}
问题:如何获取分页的实体列表并对其进行排序?哪种方法是对实体进行分页和排序的最佳方法,但也要使用聚合信息

编辑:

您对以下方法有何看法

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);        
       }
    }
公共类聚合存储
{
公共IEnumerable GetEntitiesPaged(int id)
{
返回db.Aggregate
.Include(x=>x.Aggregate)
.其中(x=>x.Id=Id)
.选择(x=>x.Entities)
.采取(20);
}
}

我可以接收包含聚合对象的实体列表(本例中为20个实体),而不是返回聚合对象。使用DDD模式中的聚合是一种好方法吗?

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

如果需要的话,可以使用一个带有读取模型的专用查询层;还有一些更原始的东西,比如
DataRow

更新

查询时应尽量不要创建聚合。这意味着不访问存储库。查询层的外观如下所示:

public interface ISomethingQuery
{
    IEnumerable<SomethingDto> GetPage(SearchSPecification specification, int pageNumber);
    // -or-
    IEnumerable<DataRow> GetPage(SearchSPecification specification, int pageNumber);
}
公共接口等轴测查询
{
IEnumerable GetPage(搜索规范,int页码);
//-或-
IEnumerable GetPage(搜索规范,int页码);
}

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

首先,您应该将写入端(命令)与读取端(查询)分开,后者调用。你可以看看这个

但是,如果您只想获得一个分页和排序的实体列表,您可以使用以下方法

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();
}
public ICollection GetSortedAggregates(AggregateListFilter筛选器,out int rowCount)
{
var query=(base.Repository.CurrentSession()作为ISession.QueryOver();
query=query.And(q=>q.Status!=StatusType.Deleted);
如果(!string.IsNullOrWhiteSpace(filter.Name))
query=query.And(q=>q.Name==filter.Name);
rowCount=query.rowCount();
开关(filter.OrderColumnName)
{
案例“.Name”:
query=filter.OrderDirection==OrderByDirections.升序?query.OrderBy(x=>x.Name).Asc:query.OrderBy(x=>x.Name).Desc;
打破
违约:
query=filter.OrderDirection==OrderByDirections.升序?query.OrderBy(x=>x.Id).Asc:query.OrderBy(x=>x.Id).Desc;
打破
}
如果(filter.CurrentPageIndex>0)
{
返回查询
.Skip((filter.CurrentPageIndex-1)*filter.PageSize)
.Take(filter.PageSize)
.List();
}
返回query.List();
}

谢谢您的回答:)当您说:“使用一个带有读取模型的专用查询层”时,您是说在获取内存中的所有数据之后再这样做(在调用GetPaged()方法之后),对吗?这样,如果我的实体有很多数据,性能就会下降,我希望避免这种情况。DataRow选项现在不是一个选项,因为我必须更改应用程序方法,我不想这样做。我编辑了我的帖子。如果你想发表评论,我很感激:)我已经更新了答案,以便对这件事有更多的了解:)为了给你一个有用的答案,我想知道你试图通过分页和排序的实体列表来实现什么。-在写或读模型中是否需要分页和排序的实体列表是否要使用此页面向用户显示实体?-您是否打算逐页读取(查询)实体,以便在您的域中强制执行某些不变量?
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();
}