C# 6.0 内插字符串(Interpolated Strings )的使用方法
看InterpolatedStrings之前,让我们先看EFCore2.0的一个新的特性:StringinterpolationinFromSqland
ExecuteSqlCommand。
varcity="London"; using(varcontext=CreateContext()) { context.Customers .FromSql($@" SELECT* FROMCustomers WHERECity={city}") .ToArray(); }
SQL语句以参数化的方式执行,所以是防字符串注入的。
@p0='London'(Size=4000) SELECT* FROMCustomers WHERECity=@p0
一直认为InterpolatedStrings只是String.Format的语法糖,传给FromSql的方法只是一个普通的字符串,已经移除了花括号,并把变量替换成了对应的值。FromSql获取不到变量信息,怎么实现参数化查询的呢?OK,让我们从头看起吧。
什么是内插字符串(InterpolatedStrings)
内插字符串是C#6.0引入的新的语法,它允许在字符串中插入表达式。
varname="world"; Console.WriteLine($"hello{name}");
这种方式相对与之前的string.Format或者string.Concat更容易书写,可读性更高。就这点,已经可以令大多数人满意了。事实上,它不仅仅是一个简单的字符串。
内插字符串(InterpolatedStrings)是什么?
用代码来回答这个问题:
varname="world"; stringstr1=$"hello{name}";//等于varstr1=$"hello{name}"; IFormattablestr2=$"hello{name}"; FormattableStringstr3=$"hello{name}";
可以看出,InterpolatedStrings可以隐式转换为3种形式。实际上式编译器默默的为我们做了转换:
varname="world"; stringstr1=string.Format("hello{0}",name);//等于varstr1=$"hello{name}"; IFormattablestr2=FormattableStringFactory.Create("hello{0}",name); FormattableStringstr3=FormattableStringFactory.Create("hello{0}",name);
- IFormattable从.netFramwork1时代就有了,只有一个ToString方法,可以传入IFormatProvider来控制字符串的格式化。今天的主角不是他。
- FormattableString伴随InterpolatedStrings引入的新类。
FormattableString是什么?
先看一段代码
varname="world"; FormattableStringfmtString=$"hello{name}"; Console.WriteLine(fmtString.ArgumentCount);//1 Console.WriteLine(fmtString.Format);//hello{0} foreach(vararginfmtString.GetArguments()) { Console.WriteLine(arg);//world Console.WriteLine(arg.GetType());//System.String }
可以看出FormattableString保存了InterpolatedStrings的所有信息,所以EFCore2.0能够以参数化的方式来执行SQL了。
EFCore中的注意事项
因为隐式转换的原因,在使用EFCore的FromSql方法和ExecuteSqlCommand方法时,需要特别小心。一不留神就会调入陷阱。
varcity="London"; using(varcontext=CreateContext()) { //方法一,非参数化 varsql=$"SELECT*FROMCustomersWHERECity={city}"; context.Customers.FromSql(sql).ToArray(); //方法二,参数化 context.Customers.FromSql($"SELECT*FROMCustomersWHERECity={city}").ToArray(); //方法三,参数化 FormattableStringfsql=$"SELECT*FROMCustomersWHERECity={city}"; context.Customers.FromSql(fsql).ToArray(); //方法四,非参数化 varsql="SELECT*FROMCustomersWHERECity=@p0"; context.Customers.FromSql(sql,city).ToArray(); }
第一种方法,因为sql的赋值被编译成String.Format方法的调用,返回的是字符串。sql变量传入FromSql方法时,又经过一次System.String到Microsoft.EntityFrameworkCore.RawSqlString隐式转换。但sql变量本身已经丢失了参数信息,所以无法实现参数化的查询。
第四种方法,也是InterpolatedStrings->String->RawSqlString的转换过程,但因为变量是分开传入FromSql方法的,所以是以参数化的方式执行的。
其他
熟悉ES2015的同学可以看看Javascript中的实现,Taggedtemplateliterals,这和InterpolatedStrings非常类似。
昨晚凌晨12点发帖,不知道为什么被移除首页了。感觉是篇幅不够的原因,重新加了点EFCore注意事项,但超过1小时没办法重新回首页了。七年来的第一篇文章,有点遗憾。希望大家喜欢。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。