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

所属分类: 软件编程 / C#教程 阅读数: 100
收藏 0 赞 0 分享

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

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

更多精彩内容其他人还在看

c#开发word批量转pdf源码分享

已经安装有Office环境,借助一些简单的代码即可实现批量Word转PDF,看下面的实例源码吧
收藏 0 赞 0 分享

c# xml API操作的小例子

这篇文章主要介绍了c# xml API操作的小例子,有需要的朋友可以参考一下
收藏 0 赞 0 分享

c#唯一值渲染实例代码

这篇文章主要介绍了c#唯一值渲染实例代码,有需要的朋友可以参考一下
收藏 0 赞 0 分享

淘宝IP地址库采集器c#代码

这篇文章主要介绍了淘宝IP地址库采集器c#代码,有需要的朋友可以参考一下
收藏 0 赞 0 分享

C#在后台运行操作(BackgroundWorker用法)示例分享

BackgroundWorker类允许在单独的专用线程上运行操作。如果需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用BackgroundWorker类方便地解决问题,下面看示例
收藏 0 赞 0 分享

c#文本加密程序代码示例

这是一个加密软件,但只限于文本加密,加了窗口控件的滑动效果,详细看下面的代码
收藏 0 赞 0 分享

c#生成站点地图(SiteMapPath)文件示例程序

这篇文章主要介绍了c#生成站点地图(SiteMapPath)文件的示例,大家参考使用
收藏 0 赞 0 分享

C# 键盘Enter键取代Tab键实现代码

这篇文章主要介绍了C# 键盘Enter键取代Tab键实现代码,有需要的朋友可以参考一下
收藏 0 赞 0 分享

C# WinForm导出Excel方法介绍

在.NET应用中,导出Excel是很常见的需求,导出Excel报表大致有以下三种方式:Office PIA,文件流和NPOI开源库,本文只介绍前两种方式
收藏 0 赞 0 分享

C#串口通信程序实例详解

在.NET平台下创建C#串口通信程序,.NET 2.0提供了串口通信的功能,其命名空间是System.IO.Ports,创建C#串口通信程序的具体实现是如何的呢?让我们开始吧
收藏 0 赞 0 分享
查看更多