Jas*_*oud 11 c# asp.net entity-framework .net-core aspnetboilerplate
我们正在实施一个查询临时表的解决方案。
在 SQL Server 上为任何表启用临时表时,SQL 将自动在表末尾添加带有额外“_History”的第二个表以跟踪历史记录。例如,如果我们有一个“student”表,SQL Server 会添加“student_History”表。
要查询学生历史,我们只需要查询学生表并FOR SYSTEM_TIME AS OF '2015-09-01 T10:00:00.7230011';在语句末尾添加即可。所以而不是写:
Select * from student
Run Code Online (Sandbox Code Playgroud)
我们会写:
Select * from student FOR SYSTEM_TIME AS OF '2015-09-01 T10:00:00.7230011'
Run Code Online (Sandbox Code Playgroud)
有没有办法在查询的末尾自动附加这个语句?
就像一个软表一样拦截查询并应用查询过滤器,但现在它没有过滤,它只是语句末尾的语句。
它可以通过扩展方法来完成,我找到了一段可以帮助你的代码:
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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
var date = DateTime.Parse("2018-08-28 16:30:00");
var students = ctx.student.ForSysTime(date);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2097 次 |
| 最近记录: |