gpt4 book ai didi

c# - 覆盖 EntityFramework SaveChanges - 获取 SQL 并调用自定义过程

转载 作者:太空狗 更新时间:2023-10-29 23:24:36 43 4
gpt4 key购买 nike

我正在寻找一种方法来覆盖 EF 中的 SaveChanges 方法/过程。我们需要以某种方式获取 SQL,阻止执行正常的更新/删除/插入,并使用生成的 SQL 来运行我们的自定义过程。

  • 正常调用SaveChanges()。让 EF 生成 SQL。
  • 获取SQL
  • 防止以正常方式执行该 SQL
  • 调用自定义存储过程(需要额外的参数等)
  • 假装我们执行了 SaveChanges(或者只返回 0)

我看到的唯一真正的问题是从 SaveChanges 方法中获取 SQL。我们会做的是这样的,理想情况下......

  1. 获取提供商/连接/等
  2. 设置事件 Hook 来处理这个问题
  3. 完成,没有代码更改/覆盖等。

我们针对 3 个字母首字母缩略词的数据库使用 MVC4 和 EF5。这里的重点是避免在每个更新操作中手动编写 SQL,并依靠 EF 为我们生成所有这些。由于该过程直接使用 SQL

是的,这不是一个好的方法(单一程序),但我们别无选择。没有任何。如果我们不能这样做,那么我们将需要编写自定义 sql。也许还有另一种方法可以强制执行此操作,即我们传递上下文并自己完成工作?然后我们可以审计“SaveChanges()”从未被调用 :D

解决方案


我使用 EFTracingProvider 作为起点来创建我自己的提供程序来执行此操作(以及其他一些操作)。您也可以 EFTracingProvider 通过将所有内容放在您的 Entities 类中并处理事件来完成此操作。您不会看到修改后的 SQL,因为此事件会在它之后触发,所以您需要自己进行日志记录。这已被精简以更好地适应网站 :)

public class MyEntities : MyBaseEntities
{

public MyEntities(): this(connectionString: "name=MyBaseEntities") {}
public MyEntities(string connectionString)
: base(MakeConnection(connectionString, "EFTracingProvider")) {}

/// <summary>
/// Insert the wrapped connection by calling the base toolkit.
private static EntityConnection MakeConnection(string connectionString, params string[] providers)
{
var conn = EntityConnectionWrapperUtils.CreateEntityConnectionWithWrappers(
connectionString,
providers
);

//get the tracing connection, so that we can attach event handlers
var us = conn.UnwrapConnection<EFTracingConnection>();
if (us != null)
{
us.CommandExecuting += BeforeExecute;
}
return conn;
}

private static void BeforeExecute(object sender, CommandExecutionEventArgs e)
{
// If an Create/Update/Delete action then we need to wrap it in our custom proc
if (IsCudAction(e.CommandTree))
{
var text = cmd.Parameters.Cast<DbParameter>().Aggregate(
cmd.CommandText,
(current, p) => current.Replace(p.ParameterName, SafeSql.Prepare(p.Value)));

cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "[dbo].[ExecuteForMe]";
cmd.Parameters.Clear();
cmd.Parameters.AddRange(new[]
{
new SqlParameter("commandText", text),
new SqlParameter("extraInfo", "logging context")
});
}
}

public static bool IsCudAction(DbCommandTree commandTree)
{
if (commandTree is DbUpdateCommandTree) return true;
if (commandTree is DbDeleteCommandTree) return true;
if (commandTree is DbInsertCommandTree) return true;
if (commandTree is DbQueryCommandTree) return false;
if (commandTree is DbFunctionCommandTree) return false;
throw new InvalidOperationException("Unknown type of CommandTree: " + commandTree.GetType().Name);
}
}

最佳答案

似乎可以使用 EF Tracing Provider 获取 SQL ... 查看此 link 中的最后一篇文章

关于c# - 覆盖 EntityFramework SaveChanges - 获取 SQL 并调用自定义过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13561209/

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