gpt4 book ai didi

c# - 支持使用 Entity Framework 6 进行 SQL Server 更改跟踪

转载 作者:可可西里 更新时间:2023-11-01 03:10:43 25 4
gpt4 key购买 nike

我有一个从现有 SQL Server 数据库生成的 Entity Framework 6 Code First 模型。数据库正在使用 SQL Server 更改跟踪,因此对于从 EF 生成的所有数据操作操作,我想设置更改跟踪上下文以将这些操作与其他外部进程所做的更改区分开来。这通常在 T-SQL 中完成,如
WITH CHANGE_TRACKING_CONTEXT (@source_id) UPDATE <table>...

我唯一能想到的就是将上面的sql子句添加到EF生成的SQL中。虽然看起来,想要修改 ORM 生成的 SQL 本身是有问题的。尽管如此,即使我想,我也不知道在哪里可以做到。 EF 命令拦截能否达到目的?

这个问题具体是关于 SQL Server 的更改跟踪功能与 EF 一起使用(不是 EF 的更改跟踪)。就 EF 而言,问题仅在于以编程方式修改 EF 生成的 SQL

最佳答案

遗憾的是,Entity Framework 6 没有对 SQL Server 更改跟踪的内置支持。但是,它确实公开了拦截功能,使您能够在执行之前修改它生成的 SQL。虽然更改 ORM 生成的 SQL 是一件应该谨慎且只有在有充分理由的情况下才能完成的事情,但在某些情况下它绝对是合适的解决方案。

EF6 公开了 IDbCommandInterceptor 类型,它使您可以 Hook 到整个查询管道。您只需要实现此接口(interface)并向 EF 注册您的拦截器。

值得注意的是,该框架将在每次INSERTUPDATEDELETE 之前调用NonQueryExecuting,使其成为 Hook 更改跟踪的好地方。

作为一个简单的例子,考虑这个拦截器:

public class ChangeTrackingInterceptor : IDbCommandInterceptor
{
private byte[] GetChangeTrackingContext()
{
// TODO: Return the appropriate change tracking context data
return new byte[] { 0, 1, 2, 3 };
}

public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
command.CommandText = "WITH CHANGE_TRACKING_CONTEXT (@change_tracking_context)\r\n" + command.CommandText;

// Create the varbinary(128) parameter
var parameter = command.CreateParameter();
parameter.DbType = DbType.Binary;
parameter.Size = 128;
parameter.ParameterName = "@change_tracking_context";
parameter.Value = GetChangeTrackingContext();
command.Parameters.Add(parameter);
}

public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
}

public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
}

public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
}

public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
}

public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
}
}

当 EF 生成任何更改 DB 状态的查询时,它会在执行查询之前调用此方法。这使您有机会使用标准 SQL 注入(inject)自定义更改跟踪上下文。

要向 EF 注册拦截器,只需在启动代码中的某处调用 DbInterception.Add:

var changeTrackingInterceptor = new ChangeTrackingInterceptor();
DbInterception.Add(changeTrackingInterceptor);

关于 IDbCommandInterceptor 接口(interface)的文档并不多,但是 this MSDN article是一个很好的起点。

关于c# - 支持使用 Entity Framework 6 进行 SQL Server 更改跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40894428/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com