相关疑难解决方法(0)

如何将System-Versioned Temporal Table与Entity Framework一起使用?

我可以在SQL Server 2016中使用时态表.遗憾的是,Entity Framework 6还不知道这个功能.是否有可能使用实体框架6 使用新的查询选项(请参阅msdn)?

我创建了一个带有员工时态表的简单演示项目:

在此输入图像描述

我使用edmx将表映射到实体(感谢Matt Ruwe):

在此输入图像描述

使用纯sql语句一切正常:

using (var context = new TemporalEntities())
{
    var employee = context.Employees.Single(e => e.EmployeeID == 2);
    var query = 
      $@"SELECT * FROM [TemporalTest].[dbo].[{nameof(Employee)}]
         FOR SYSTEM_TIME BETWEEN
         '0001-01-01 00:00:00.00' AND '{employee.ValidTo:O}'
         WHERE EmployeeID = 2";
    var historyOfEmployee = context.Employees.SqlQuery(query).ToList();
}    
Run Code Online (Sandbox Code Playgroud)

是否可以在没有纯SQL的情况下将历史记录功能添加到每个实体?我的解决方案作为实体扩展与反射来操纵SQL查询IQuerable并不完美.是否有现有的扩展或库来执行此操作?

编辑:(基于Pawel的评论)

我试图使用表值函数:

CREATE FUNCTION dbo.GetEmployeeHistory(
    @EmployeeID int, 
    @startTime datetime2, 
    @endTime datetime2)
RETURNS TABLE
AS
RETURN 
(
    SELECT 
        EmployeeID,
        [Name], 
        Position, 
        Department, 
        [Address], …
Run Code Online (Sandbox Code Playgroud)

c# sql entity-framework temporal sql-server-2016

20
推荐指数
1
解决办法
3956
查看次数

实体框架不使用时态表

我正在使用数据库第一实体框架6.在将我的模式中的一些表更改为临时表后,我在尝试插入新数据时开始收到以下错误:

Cannot insert an explicit value into a GENERATED ALWAYS column in table '<MyDatabase>.dbo.<MyTableName>. Use INSERT with a column list to exclude the GENERATED ALWAYS column, or insert a DEFAULT into GENERATED ALWAYS column.

看起来EF正在尝试更新PERIOD由系统管理的列的值.

从EDMX文件中删除列似乎可以解决问题,但这不是一个可行的解决方案,因为每次从数据库重新生成模型时都会重新添加列.

c# sql-server temporal-database entity-framework-6 sql-server-2016

14
推荐指数
2
解决办法
5321
查看次数

仅将IDbInterceptor挂接到EntityFramework DbContext一次

IDbCommandInterceptor接口是不是非常有据可查.我只发现了一些稀缺的教程:

还有一些问题:


这些是关于挂钩的建议我发现:

1 - 静态DbInterception类:

DbInterception.Add(new MyCommandInterceptor());
Run Code Online (Sandbox Code Playgroud)

2 - 在DbConfiguration课堂上做上述建议

public class MyDBConfiguration : DbConfiguration {
    public MyDBConfiguration() {
        DbInterception.Add(new MyCommandInterceptor());
    }
}
Run Code Online (Sandbox Code Playgroud)

3 - 使用配置文件:

<entityFramework>
  <interceptors>
    <interceptor type="EFInterceptDemo.MyCommandInterceptor, EFInterceptDemo"/>
  </interceptors>
</entityFramework>
Run Code Online (Sandbox Code Playgroud)

虽然我无法弄清楚如何将DbConfiguration类挂钩到DbContext,并且既没有放入typeconfig方法的部分.我发现的另一个例子似乎建议您编写记录器的命名空间:

type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework"
Run Code Online (Sandbox Code Playgroud)

我注意到了DataBaseLogger工具IDisposable,IDbConfigurationInterceptor
IDbInterceptor.IDbCommandInterceptor也实现了IDbInterceptor,所以我尝试(没有成功)格式化它像这样:

type="DataLayer.Logging.MyCommandInterceptor, DataLayer"
Run Code Online (Sandbox Code Playgroud)

当我DbInterception直接调用静态类时,它每次调用都会添加另一个拦截器.所以我的快速而肮脏的解决方案是利用静态构造函数:

//This partial class is …
Run Code Online (Sandbox Code Playgroud)

c# logging entity-framework interceptor entity-framework-6

8
推荐指数
2
解决办法
4446
查看次数

从 IDbCommandInterceptor 的实现获取 DbContext

我正在使用一个IDbCommandInterceptor实现:

\n\n
public class MyInterceptor : IDbCommandInterceptor\n{\n    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)\n    {\n        var context = interceptionContext.DbContexts.FirstOrDefault();\n    }\n\n    public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)\n    {\n    }\n\n    public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)\n    {\n    }\n\n    public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)\n    {\n    }\n\n    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)\n    {\n    }\n\n    public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)\n    {\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

以此注入:

\n\n
public class TestContext : System.Data.Entity.DbContext\n{\n    // \xe2\x80\xa6\n\n    public TestContext()\n        : base("TestConnectionString")\n    {\n        Database.SetInitializer<TestContext>(null);\n        DbInterception.Add(new MyInterceptor());\n    }\n}\n …
Run Code Online (Sandbox Code Playgroud)

c# entity-framework interceptor entity-framework-6

5
推荐指数
1
解决办法
3580
查看次数