【问题标题】:C# override Entity Framework Database.ExecuteSqlCommandC# 覆盖实体框架 Database.ExecuteSqlCommand
【发布时间】:2020-01-14 14:25:30
【问题描述】:

有没有办法让我重写 Database.ExecuteSqlCommand 以便我每次调用它时都可以强制运行存储过程(以及实际的 sql 是什么)?

【问题讨论】:

  • 你说的是什么意思,这样我每次调用它时都可以强制运行存储过程(以及实际的sql)”?你能告诉我们你的 SQL 是什么吗?
  • 我相信这意味着在使用 ExecuteSqlCommand 执行 Raw SQL 代码之前运行一个 SP
  • 我怀疑这是可能的。 Database DbContext 的属性没有设置器,所以你不能用你的实现替换 Database 实例。
  • 您可以很容易地覆盖SaveChanges 方法,但这只会帮助您在创建/更新/删除时运行存储过程,而不是检索数据。如果您认为这会让您到达您需要的地方,我可以提供一个示例

标签: c# sql-server asp.net-mvc entity-framework


【解决方案1】:

简而言之,你不能。至少不是通过覆盖。 For you to override a method it has to originally be abstract or virtual.

您可以在 DbContext 类中创建一个方法来处理存储过程的执行,然后再执行查询。

【讨论】:

  • 你说的是添加扩展方法吗?
  • 可能是,但扩展仅用于准备查询(在此处附加 SP)。我说的是在 Context 类中创建一个完整的方法。
【解决方案2】:

不,您不能覆盖Database.ExecuteSqlCommand,因为这些方法不是虚拟的。此外,通常直接从服务/控制器调用Database.ExecuteSqlCommand 不是一个好主意。相反,您可以拥有另一个抽象级别,您可以拥有在执行 SQL 命令之前调用存储过程的方法。

    public int RunSqlCommand(string sql, params object[] parameters)
    {
        _database.ExecuteSqlCommand("YourStoredProcedure @p0", parameters: new[] {"Parameter1"});
        _database.ExecuteSqlCommand (sql, parameters);
    }

【讨论】:

    【解决方案3】:

    我最终对现有代码的影响最小的做法是只使用连接拦截器。每当打开连接时,我都会先运行我的存储过程:

    public class myInterceptor : IDbConnectionInterceptor { public void Opened(DbConnection connection, DbConnectionInterceptionContext interceptionContext) { //do my SP here } }

    【讨论】:

      【解决方案4】:

      我想到的一些想法是实现自己的方法(覆盖或扩展数据库),在之前“强制”执行存储过程,然后运行作为参数传递的 SQL。 其他一些选择是使用 Dapper 并调用您的过程,然后调用您的 SQL。

      【讨论】:

      • 你建议如何重写非虚拟方法?
      猜你喜欢
      • 2013-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多