簡體   English   中英

使用 Linq2Sql 的臨時表

[英]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的最簡單方法(如果有的話)是什么?

我試過的:

  1. 在執行 SQL 查詢時,尋找一種配置所需系統時間的方法。 問題:我找不到方法。
  2. 通過值 function 的表公開查詢,允許將@validityDate作為參數傳遞。 問題:我無法使用 Linq2Sql 傳遞參數(或者至少我沒有弄清楚如何)。
  3. 創建一個表值 function 執行連接(而不是讓 EF 執行連接),以便可以使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM