[英]Querying Data in a System-Versioned Temporal Table in Entity Framework Core
我們正在實施一個查詢臨時表的解決方案。
在 SQL Server 上為任何表啟用臨時表時,SQL 將自動在表末尾添加帶有額外“_History”的第二個表以跟蹤歷史記錄。 例如,如果我們有一個“student”表,SQL Server 會添加“student_History”表。
要查詢學生歷史,我們只需要查詢學生表並添加FOR SYSTEM_TIME AS OF '2015-09-01 T10:00:00.7230011';
在聲明的最后。 所以而不是寫:
Select * from student
我們會寫:
Select * from student FOR SYSTEM_TIME AS OF '2015-09-01 T10:00:00.7230011'
有沒有辦法在查詢的末尾自動附加這個語句?
就像一個軟表一樣攔截查詢並應用查詢過濾器,但現在它沒有過濾,它只是語句末尾的語句。
它可以通過擴展方法來完成,我找到了一段可以幫助你的代碼:
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Migrations;
using System;
using System.Linq;
namespace core
{
public static class Extensions
{
public static void AddTemporalTableSupport(this MigrationBuilder builder, string tableName, string historyTableSchema)
{
builder.Sql($@"ALTER TABLE {tableName} ADD
SysStartTime datetime2(0) GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
SysEndTime datetime2(0) GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime);");
builder.Sql($@"ALTER TABLE {tableName} SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = {historyTableSchema}.{tableName} ));");
}
public static DbContext GetDbContext<T>(this DbSet<T> dbSet) where T : class
{
var infrastructure = dbSet as IInfrastructure<IServiceProvider>;
return (infrastructure.Instance.GetService(typeof(ICurrentDbContext)) as ICurrentDbContext).Context;
}
public static string GetTableName<T>(this DbSet<T> dbSet) where T : class
{
var entityType = dbSet.GetDbContext().Model.GetEntityTypes().FirstOrDefault(t => t.ClrType == typeof(T))
?? throw new ApplicationException($"Entity type {typeof(T).Name} not found in current database context!");
var tableNameAnnotation = entityType.GetAnnotation("Relational:TableName");
return tableNameAnnotation.Value.ToString();
}
public static IQueryable<T> ForSysTime<T>(this DbSet<T> dbSet, DateTime time) where T : class
{
return dbSet.FromSql($"SELECT * FROM dbo.[{dbSet.GetTableName()}] FOR SYSTEM_TIME AS OF {{0}}", time.ToUniversalTime());
}
}
}
用法:
var date = DateTime.Parse("2018-08-28 16:30:00");
var students = ctx.student.ForSysTime(date);
你可以試試這個 nuget pacakge https://www.nuget.org/packages/EntityFrameworkCore.SqlServer.TemporalTable/
IT支持:
最新版本的 Entity Framework Core (6) 支持時態表。
正如此處提到的Microsoft devBlogs EF Core 6.0 支持:
查詢歷史數據可以看這里
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.