[英]Temporal tables with Linq2Sql
我有一个通用存储库,可以通过 ID 获取实体或获取所有实体:
internal class Repository<TEntity> : IRepository<TEntity>
where TEntity : BaseEntity
{
protected SaiContext Context { get; }
/// <summary>Gets the entity set.</summary>
protected virtual DbSet<TEntity> Set => Context.Set<TEntity>();
public Repository(SaiContext context)
{
Context = context;
}
public async Task<TEntity> GetAsync(int entityId, IEnumerable<string> includeProperties = null)
{
try
{
return await GetQueryableWithIncludes(includeProperties).SingleAsync(entity => entity.Id == entityId);
}
catch (InvalidOperationException)
{
throw new EntityNotFoundException(typeof(TEntity), entityId);
}
}
public async Task<IEnumerable<TEntity>> GetAllAsync(IEnumerable<string> includeProperties = null)
{
return await GetQueryableWithIncludes(includeProperties).ToListAsync();
}
protected IQueryable<TEntity> GetQueryableWithIncludes(IEnumerable<string> includeProperties = null)
{
IQueryable<TEntity> queryable = Set;
if (includeProperties == null)
{
return queryable;
}
foreach (var propertyName in includeProperties)
{
queryable = queryable.Include(propertyName);
}
return queryable;
}
}
在为实体关系配置 DbContext 后,导航属性以及所有 rest 正在为所有实体正确加载。
现在我被要求使用临时 SQL 表,以便所有实体都有一个有效范围。
使用 SQL 我会在查询中包含FOR SYSTEM_TIME AS OF @validityDate
。
调整现有实现以尊重@validityDate
的最简单方法(如果有的话)是什么?
我试过的:
@validityDate
作为参数传递。 问题:我无法使用 Linq2Sql 传递参数(或者至少我没有弄清楚如何)。context.FromSqlRaw(<query>)
调用它。 ISSUE: 如何创建 c# object 树? (由于存在一对多的关系,因此返回了多行) 我发现使用时态表的所有示例都使用FromSqlRaw
。 如果可能的话,我想避免它,因为这意味着整个数据库上下文配置变得无用,并且必须包含映射的附加代码。
我找到了efcore-temporal-query ( nuget ) 库的解决方案。
该代码已被改编为使用README中描述的临时表。
存储库方法现在接受可选参数有效性日期:
public async Task<TEntity> GetAsync(int entityId, DateTime? validityDate = null, IEnumerable<string> includeProperties = null)
{
try
{
var query = GetQueryableWithIncludes(includeProperties);
query = GetQueryableWithValidityDate(query, validityDate);
return await query.SingleAsync(entity => entity.Id == entityId);
}
catch (InvalidOperationException)
{
throw new EntityNotFoundException(typeof(TEntity), entityId);
}
}
protected IQueryable<TEntity> GetQueryableWithIncludes(IEnumerable<string> includeProperties = null)
{
IQueryable<TEntity> queryable = Set;
if (includeProperties == null)
{
return queryable;
}
foreach (var propertyName in includeProperties)
{
queryable = queryable.Include(propertyName);
}
return queryable;
}
private static IQueryable<TEntity> GetQueryableWithValidityDate(IQueryable<TEntity> query, DateTime? validityDate)
{
return validityDate.HasValue ? query.AsOf(validityDate.Value) : query;
}
历史查询的相关部分是query.AsOf(validityDate.Value)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.