【问题标题】:Is there have any difference between string concat and string interpolation in EF Core?EF Core 中的字符串 concat 和字符串插值之间有什么区别吗?
【发布时间】:2020-10-14 18:02:11
【问题描述】:

我使用 asp.net core 2.1 和 EF Core 2。 我曾调用 FromSql() 来使用原始查询。但是发生了一些奇怪的结果。

var finds = db.JournalInfos.FromSql<JournalInfo>($"SELECT * FROM `journalinfos` WHERE `journalinfos`.`Date` LIKE '{dateKey}%' ORDER BY `Index`").ToList();
var b = finds.Count(); //the count is 0 (It can't count noramlly)

var test = db.JournalInfos.FromSql<JournalInfo>("SELECT * FROM `journalinfos` WHERE `journalinfos`.`Date` LIKE '" + dateKey + "%' ORDER BY `Index`").ToList();
var a = test.Count(); //but in here, the count is normal (1054)

我认为 2 个 sql 字符串之间没有任何区别。

我尝试更改这两个语句的顺序,以查看在同一实体上调用 FromSql 两次以上是否存在问题,但结果相同。一种使用字符串插值,另一种使用 + 连接字符串。

正如你在上面看到的,他们的 string.Equal() 结果也是一样的。 (但使用字符串插值情况,它不会返回有效计数) 但是如果我使用字符串变量来存储每个值并将其传递给每个 FromSql 参数,那么它们的查询结果是相同的。 (有效)

string sql1 = $"SELECT * FROM `journalinfos` WHERE `journalinfos`.`Date` LIKE '{dateKey}%' ORDER BY `Index`";
var finds = db.JournalInfos.FromSql<JournalInfo>(sql1).ToList();
var b = finds.Count(); //Now, it can count normally (1054)

string sql2 = "SELECT * FROM `journalinfos` WHERE `journalinfos`.`Date` LIKE '" + dateKey + "%' ORDER BY `Index`";
var test = db.JournalInfos.FromSql<JournalInfo>(sql2).ToList();
var a = test.Count(); //Also too. (1054)

c#或EF Core中的string+concatnation和stringinterpolation有什么区别吗?

【问题讨论】:

  • 技术上,两个查询是一样的,只是写法不同。我假设finds List 在第二个查询执行时被清除。能不能一步一步看。
  • 这里有一个细微的差别,EF Core 2.x 能够分辨出FormattableStringstring 值之间的区别。这也是 EF Core 3.x 中 FromSql 被 FromSqlRaw 和 FromSqlInterpolated 取代的部分原因。

标签: asp.net entity-framework entity-framework-core


【解决方案1】:

内插字符串

内插字符串可以转换为调用String.Format()。当您将其存储在字符串变量中时会发生这种情况:

string sql1 = $"...";
var finds = db.JournalInfos.FromSql<JournalInfo>(sql1);

但是,如果您直接传递插值字符串(如屏幕截图中所示),根据docsmethod parameters,它将是FormattableString 类型:

var finds = db.JournalInfos.FromSql<JournalInfo>($"...");

在第二种情况下,数据库提供程序会格式化您的查询并转义危险字符以避免 SQL 注入攻击。如果您想找出确切的区别,您必须在 EF Core 中启用敏感数据日志记录才能查看实际查询。

LINQ 方法

对于这个特定问题,可能有比使用原始 SQL 查询更简单的解决方案。 LINQ 扩展方法被编译为 SQL,在 SQL 注入方面是安全的,并且如果您的数据库模型发生更改,则更容易维护。

DateTime date; // This is the same variable like in line 1603 on your screenshot

DateTime minInclusive = new DateTime(date.Year, date.Month, 1);
DateTime maxExclusive = minInclusive.AddMonths(1);

var finds = db.JournalInfos
    .Where(journal => journal.Date >= minInclusive && journal < maxExclusive)
    .OrderBy(journal => journal.Index)
    .ToList();

【讨论】:

    猜你喜欢
    • 2020-03-09
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 2017-01-29
    • 2010-09-13
    相关资源
    最近更新 更多