[英]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.