好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

C# 6.0 内插字符串(Interpolated Strings )的使用方法

看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 Customers

WHERE 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);

IFormattable 从.net Framwork 1 时代就有了,只有一个 ToString 方法,可以传入 IFormatProvider 来控制字符串的格式化。今天的主角不是他。 FormattableString 伴随Interpolated Strings引入的新类。

FormattableString 是什么?

先看一段代码

?

var name = "world" ;

FormattableString fmtString = $ "hello {name}" ;

Console.WriteLine(fmtString.ArgumentCount); //1

Console.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小时没办法重新回首页了。七年来的第一篇文章,有点遗憾。希望大家喜欢。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://HdhCmsTestcnblogs测试数据/csproj/p/Interpolated_Strings.html

dy("nrwz");

查看更多关于C# 6.0 内插字符串(Interpolated Strings )的使用方法的详细内容...

  阅读:46次