按版本分组
Group by version
The Setup
public abstract class Entity
{
public Guid Id { get; set; }//Primary key
public int Version { get; set; }//Primary key
public DateTime Created { get; set; }
public User CreatedBy { get; set; }
public bool IsDeleted { get; set; }
}
Id和Version都是主键。
实体在创建时自动生成一个 Id,并具有默认版本“0”。更新实体时,将添加另一条具有相同 ID 和版本“1”等的记录...当实体为 "deleted" 时,将添加另一条具有相同 ID、版本 + 1 且带有 [=45] 的记录=] IsDeleted 设置为 "true".
The Question
在我的存储库中,我想要一个 returns 可查询
的方法
- 按相同 ID 分组的实体
- 最高版本(=最新版本
实体的)
- IsDeleted = false
简而言之:我想检索一个实体列表,只有它们的最新记录(当实体未设置为 "IsDeleted" 时)
The Attempt
我尝试了两种不同的方法来解决这个问题。 correct/better 是哪一个? (或其他建议?)
选项 1:
public IQueryable<TEntity> Get<TEntity>(int page, int size) where TEntity : Entity
{
return _context
.Query<TEntity>()
.OrderByDescending(x => x.Version)
.GroupBy(x => x.Id)
.SelectMany(x => x)
.Where(x => !x.IsDeleted)
.Skip(page * size)
.Take(size);
}
选项 2:
public IQueryable<TEntity> Get<TEntity>(int page, int size) where TEntity : Entity
{
return _context
.Query<TEntity>()
.GroupBy(d => d.Id)
.Select(g => g.OrderByDescending(d => d.Version))
.OrderByDescending(e => e.First().Version)
.SelectMany(e => e)
.Where(x => !x.IsDeleted)
.Skip(page * size)
.Take(size);
}
我认为您的选项 2 几乎可以按您希望的方式工作(基于评论)。您只需要从每个组中删除 .OrderByDescending(e => e.First().Version)
然后 select e.First()
:
public IQueryable<TEntity> Get<TEntity>(int page, int size) where TEntity : Entity
{
return _context
.Query<TEntity>()
.GroupBy(d => d.Id)
.Select(g => g.OrderByDescending(d => d.Version))
.Select(e => e.First())
.Where(x => !x.IsDeleted)
.Skip(page * size)
.Take(size);
}
查看您的要求:
- 按相同 ID 分组的实体
- 最高版本(=实体的最新版本)
- 未删除
如果在我看来你想要每个实体的最高未删除版本。
为了说得更清楚,我再说说文档的版本。您想要文档被删除之前的最后一个文档版本,或者如果尚未删除则为最后一个版本。
我的建议是先删除所有已删除的文档版本。然后将文档分组到具有相同 Id 的组中。
现在每个组都包含文档的所有未删除版本)。之后你拿最高版本号的文档。
var result = entities // from the collection of document
.Where(entity => !entity.IsDeleted) // keep the non-deleted ones
.GroupBy(entity => entity.Id) // group them into groups with same Id
// now every group contains all non-deleted versions of a document
// select the newest document, // to do this
.Select(group => group // order all items in a group by
.OrderByDescending(groupItem => groupItem.Version) // descending Version number
.FirstOrDefault()); // and select the first one
有个GroupBy overload that combines GroupBy and Select:
// group the remaining non-deleted items into groups with same Id
.GroupBy(entity => entity.Id
(id, entitiesWithThisId => entitiesWithThisId.OrderByDescending(entity => entity.Version)
// order all entities of a group by descending Version number
.FirstOrDefault()); // and select the first one
The Setup
public abstract class Entity
{
public Guid Id { get; set; }//Primary key
public int Version { get; set; }//Primary key
public DateTime Created { get; set; }
public User CreatedBy { get; set; }
public bool IsDeleted { get; set; }
}
Id和Version都是主键。 实体在创建时自动生成一个 Id,并具有默认版本“0”。更新实体时,将添加另一条具有相同 ID 和版本“1”等的记录...当实体为 "deleted" 时,将添加另一条具有相同 ID、版本 + 1 且带有 [=45] 的记录=] IsDeleted 设置为 "true".
The Question
在我的存储库中,我想要一个 returns 可查询
的方法- 按相同 ID 分组的实体
- 最高版本(=最新版本 实体的)
- IsDeleted = false
简而言之:我想检索一个实体列表,只有它们的最新记录(当实体未设置为 "IsDeleted" 时)
The Attempt
我尝试了两种不同的方法来解决这个问题。 correct/better 是哪一个? (或其他建议?)
选项 1:
public IQueryable<TEntity> Get<TEntity>(int page, int size) where TEntity : Entity
{
return _context
.Query<TEntity>()
.OrderByDescending(x => x.Version)
.GroupBy(x => x.Id)
.SelectMany(x => x)
.Where(x => !x.IsDeleted)
.Skip(page * size)
.Take(size);
}
选项 2:
public IQueryable<TEntity> Get<TEntity>(int page, int size) where TEntity : Entity
{
return _context
.Query<TEntity>()
.GroupBy(d => d.Id)
.Select(g => g.OrderByDescending(d => d.Version))
.OrderByDescending(e => e.First().Version)
.SelectMany(e => e)
.Where(x => !x.IsDeleted)
.Skip(page * size)
.Take(size);
}
我认为您的选项 2 几乎可以按您希望的方式工作(基于评论)。您只需要从每个组中删除 .OrderByDescending(e => e.First().Version)
然后 select e.First()
:
public IQueryable<TEntity> Get<TEntity>(int page, int size) where TEntity : Entity
{
return _context
.Query<TEntity>()
.GroupBy(d => d.Id)
.Select(g => g.OrderByDescending(d => d.Version))
.Select(e => e.First())
.Where(x => !x.IsDeleted)
.Skip(page * size)
.Take(size);
}
查看您的要求:
- 按相同 ID 分组的实体
- 最高版本(=实体的最新版本)
- 未删除
如果在我看来你想要每个实体的最高未删除版本。
为了说得更清楚,我再说说文档的版本。您想要文档被删除之前的最后一个文档版本,或者如果尚未删除则为最后一个版本。
我的建议是先删除所有已删除的文档版本。然后将文档分组到具有相同 Id 的组中。
现在每个组都包含文档的所有未删除版本)。之后你拿最高版本号的文档。
var result = entities // from the collection of document
.Where(entity => !entity.IsDeleted) // keep the non-deleted ones
.GroupBy(entity => entity.Id) // group them into groups with same Id
// now every group contains all non-deleted versions of a document
// select the newest document, // to do this
.Select(group => group // order all items in a group by
.OrderByDescending(groupItem => groupItem.Version) // descending Version number
.FirstOrDefault()); // and select the first one
有个GroupBy overload that combines GroupBy and Select:
// group the remaining non-deleted items into groups with same Id
.GroupBy(entity => entity.Id
(id, entitiesWithThisId => entitiesWithThisId.OrderByDescending(entity => entity.Version)
// order all entities of a group by descending Version number
.FirstOrDefault()); // and select the first one