时间:2021-05-20
看Interpolated Strings之前,让我们先看EF Core 2.0 的一个新的特性:String interpolation in FromSql and
ExecuteSqlCommand。
var city = "London";using (var context = CreateContext()){ context.Customers .FromSql($@" SELECT * FROM Customers WHERE City = {city}") .ToArray();}SQL语句以参数化的方式执行,所以是防字符串注入的。
@p0='London' (Size = 4000)SELECT *FROM CustomersWHERE City = @p0一直认为Interpolated Strings只是String.Format的语法糖,传给FromSql的方法只是一个普通的字符串,已经移除了花括号,并把变量替换成了对应的值。FromSql获取不到变量信息,怎么实现参数化查询的呢? OK,让我们从头看起吧。
什么是内插字符串 (Interpolated Strings)
内插字符串是C# 6.0 引入的新的语法,它允许在字符串中插入表达式。
var name = "world";Console.WriteLine($"hello {name}");这种方式相对与之前的string.Format或者string.Concat更容易书写,可读性更高。就这点,已经可以令大多数人满意了。事实上,它不仅仅是一个简单的字符串。
内插字符串 (Interpolated Strings) 是什么?
用代码来回答这个问题:
var name = "world";string str1 = $"hello {name}"; //等于 var str1 = $"hello {name}";IFormattable str2 = $"hello {name}";FormattableString str3 = $"hello {name}";可以看出,Interpolated Strings 可以隐式转换为3种形式。实际上式编译器默默的为我们做了转换:
var name = "world";string str1 = string.Format("hello {0}",name); //等于 var str1 = $"hello {name}";IFormattable str2 = FormattableStringFactory.Create("hello {0}",name);FormattableString str3 = FormattableStringFactory.Create("hello {0}",name);FormattableString 是什么?
先看一段代码
var name = "world";FormattableString fmtString = $"hello {name}";Console.WriteLine(fmtString.ArgumentCount); //1Console.WriteLine(fmtString.Format); //hello {0}foreach (var arg in fmtString.GetArguments()){ Console.WriteLine(arg); //world Console.WriteLine(arg.GetType()); //System.String}可以看出FormattableString保存了Interpolated Strings的所有信息,所以EF Core 2.0能够以参数化的方式来执行SQL了。
EF Core 中的注意事项
因为隐式转换的原因,在使用EF Core的FromSql 方法和 ExecuteSqlCommand方法时,需要特别小心。一不留神就会调入陷阱。
var city = "London";using (var context = CreateContext()){ //方法一,非参数化 var sql = $" SELECT * FROM Customers WHERE City = {city}"; context.Customers.FromSql(sql).ToArray(); //方法二,参数化 context.Customers.FromSql($" SELECT * FROM Customers WHERE City = {city}").ToArray(); //方法三,参数化 FormattableString fsql = $" SELECT * FROM Customers WHERE City = {city}"; context.Customers.FromSql(fsql).ToArray(); //方法四,非参数化 var sql = " SELECT * FROM Customers WHERE City = @p0"; context.Customers.FromSql(sql, city).ToArray();}第一种方法,因为sql的赋值被编译成String.Format方法的调用,返回的是字符串。sql变量传入FromSql方法时,又经过一次System.String 到Microsoft.EntityFrameworkCore.RawSqlString隐式转换。但sql变量本身已经丢失了参数信息,所以无法实现参数化的查询。
第四种方法, 也是Interpolated Strings -> String -> RawSqlString的转换过程,但因为变量是分开传入FromSql方法的,所以是以参数化的方式执行的。
其他
熟悉ES2015的同学可以看看Javascript中的实现,Tagged template literals,这和Interpolated Strings 非常类似。
昨晚凌晨12点发帖,不知道为什么被移除首页了。感觉是篇幅不够的原因,重新加了点EF Core注意事项,但超过1小时没办法重新回首页了。七年来的第一篇文章,有点遗憾。希望大家喜欢。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
下面是C#判断字符串是否是数字的代码://////判断字符串是否是数字///publicstaticboolIsNumber(strings){ if(s
本文实例讲述了C#实现翻转字符串的方法。分享给大家供大家参考。具体实现方法如下:FuncReverseString=delegate(strings){char
本文实例讲述了C#删除字符串中重复字符的方法。分享给大家供大家参考。具体实现方法如下:复制代码代码如下:#region删除重复字符strings="sdffff
本文实例讲述了C#实现去除Strings中空格的方法,分享给大家供大家参考。具体实现方法如下:一般来说,你或许知道你能使用String.Trim方法去除字符串的
Thymeleaf主要使用org.thymeleaf.expression.Strings类处理字符串,在模板中使用#strings对象来处理字符串。开发环境: