首页 > 解决方案 > 如果我使用参数重载,FromSqlRaw 和 FromSqlInterpolated 返回空集

问题描述

我在MySQL 8.x数据库中定义了一个名为“SearchContacts”的存储过程,它只有一个参数:

SearchContacts(searchQuery VARCHAR(255))

在我的ASP.NET Core 3.1 MVC项目中,要调用此 SP,我有一个DbContext,其中包含此字段及其相关OnModelCreating配置:

protected DbSet<SearchContacts> SearchContactsSP { get; set; }

...

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    ...

    modelBuilder.Entity<SearchContacts>(entity =>
    {
        entity.HasKey(k => k.IdContact);
    }

    ...
}

前提:数据库不为空。

如果我运行此代码:

string search = "claire";

var result = SearchContactsSP.FromSqlRaw(
    sql: $"CALL `SearchContacts`('{search}')"
)
.IgnoreQueryFilters()
.AsNoTracking();

一切正常,我返回了一个非空集。

因为我知道这可能是一个严重的 SQL 注入漏洞,所以我开始用这个逻辑替换上面的代码:

var result = SearchContactsSP.FromSqlRaw(
    sql: "CALL `SearchContacts`('{0}')",
    search
)
.IgnoreQueryFilters()
.AsNoTracking();

但它返回空集。这同样会发生:

var result = SearchContactsSP.FromSqlInterpolated(
    sql: $"CALL `SearchContacts`('{search}')"
)
.IgnoreQueryFilters()
.AsNoTracking();

为什么会这样?


欢迎任何其他更好地运行 SP 的解决方案,因为我对我发现调用它的方式并不满意。


提供者:Pomelo.EntityFrameworkCore.MySql.Json.Microsoft (3.2.4)

标签: c#mysqlasp.net-core

解决方案


这更像是调试信息而不是答案,因为从您编写的内容来看,它应该可以完美运行:

在你的 appsettings.json 你应该改变这个:

{
  "Logging": {
    "LogLevel": {
      "Microsoft": "Warning"
    }
  }
}

对此:

{
  "Logging": {
    "LogLevel": {
      "Microsoft": "Debug"
    }
  }
}

这将让您在“输出”窗口中看到生成的 SQL,以便您检查它。

此外,您应该尝试更改 EFCore 提供程序,例如更改为正常的:MySql.Data.EntityFrameworkCore 以排除提供程序错误。

如果没有任何帮助,请制作一个简单的示例应用程序来找出问题,否则它可以隐藏在您拥有的任何代码中。仔细检查您写的内容是否正确,并且您没有遗漏重要信息,例如列的确切数据类型。

编辑

您可以尝试 ADO.NET 方法吗?:

SearchContactsSP.Database.ExecuteSqlCommand("SearchContacts (@p0)", parameters: new[] { search });

也许 EF 对您从所谓的表上下文开始查询感到困惑......

顺便说一句,请结合@Evk 的建议以删除参数值周围的引号 - 一旦它是一个不需要引号的参数,它就会从 SQL 结构中删除。报价只会再次包装它的价值。

思路来源:教程


推荐阅读