深入理解 LINQ to SQL 生成的 SQL 语句
Ø 简介
在 C# 中与数据交互最常用的语句就是 LINQ 了,而 LINQ to SQL 是最直接与数据库打交道的语句,它可以根据 LINQ 语法生成对应的 SQL 语句,在数据库中去执行。本文主要研究什么样 LINQ 语句会生成什么样 SQL 语句,从而确保编写 LINQ 语句时,便知道该语句会执行什么样的 SQL 语句,得到什么结果,这是很有必要的。因为很多时候会考虑到 SQL 效率问题,和数据是否有误等问题。主要包括:
1. 插入数据
2. 判断记录是否存在
3. 左连接情况下,判断某字段是否为 null 的写法
4. 连接查询关联不同类型(string & int)字段
5. 关联表(一对多关系),一条语句查询主表与子表数据
6. 使用 IQueryable<T> 类型的变量,嵌入 LINQ 查询语法中
7. 常见的查询技巧
8. 使用对象集合进行连接查询
1. 插入数据
1) LINQ 语句
DataContext.CustomerTodos.Add(entity);
DataContext.SaveChanges();
2) 生成 SQL
exec 、49667的客户与用户记录
var dataList = (from t1 in DataContext.Customers
where t1.Id == 45357 || t1.Id == 49667
select new CustomerModel()
{
Id = (int)t1.Id,
Name = t1.Name,
UserList = (from d1 in DataContext.UserInfoes
where d1.CustomerId == t1.Id
select new CustomerModel.UserInfoModel()
{
Id = d1.id,
UserName = d1.userName
}).ToList()
}).ToList();
2) 生成 SQL
SELECT
3) 执行结果

4) 分析
1. 首先,我们定义了一个 IQueryable<T> 类型的变量,然后在使用这个变量作为数据源,进行关联查询。可见,在生成的 SQL 中直接进行了内连接查询,并输出相关字段。
2. 这种写法主要是可以方便多次查询,可以多次利用这个 allCustomers 条SQL)
exec
3. 分析
1) 每次遍历,都会生成不同的SQL,并查询数据库。
2) 通常情况下,不建议这样去遍历查询,可以先查询出所需的记录,再进行遍历。
3) 根据不同条件生成对应 SQL
1. LINQ 语句
var query3 = (from t1 in dbContext.Grades
where t1.GradeName.Contains("年级")
orderby t1.GradeId descending
select t1);
for (int i = 1; i <= 3; i++)
{
var entity = query3.Where(o => o.GradeId == i).FirstOrDefault();
Console.WriteLine("获取记录:{0}", (entity != null ? entity.GradeId : 0));}
2. 生成 SQL(类似的3条SQL)
exec sp_executesql N'SELECT TOP (1)
[Project1].[GradeId] AS [GradeId],
[Project1].[GradeName] AS [GradeName],
[Project1].[Remark] AS [Remark]
FROM ( SELECT
[Extent1].[GradeId] AS [GradeId],
[Extent1].[GradeName] AS [GradeName],
[Extent1].[Remark] AS [Remark]
FROM [dbo].[Grade] AS [Extent1]
WHERE ([Extent1].[GradeName] LIKE N''%年级%'') AND ([Extent1].[GradeId] = @p__linq__0) AND (@p__linq__0 IS NOT NULL)
) AS [Project1]
ORDER BY [Project1].[GradeId] DESC',N'@p__linq__0 int',@p__linq__0=1
3. 分析
1) 每次遍历,都会生成不同的SQL,并查询数据库。
2) 并将条件以 AND(与)进行追加。
3) 通常情况下,不建议这样去遍历查询,可以先查询出所需的记录,再进行遍历。
8. 使用对象集合进行连接查询
1) LINQ 语句
Class1[] objects = new Class1[]
{
new Class1 { Id = 1, Name = "Name1" },
new Class1 { Id = 2, Name = "Name2" },
new Class1 { Id = 3, Name = "Name3" }
};
var query1 = (from t1 in objects
join t3 in dbContext.Grades on t1.Id equals t3.GradeId
where t1.Name.Contains("2") && t3.GradeName.Contains("二")
select new { t3.GradeId, t1.Name, t3.GradeName });
foreach (var item in query1)
{
Console.WriteLine("获取记录:{0},{1},{2}", item.GradeId, item.Name, item.GradeName);
}
2) 生成 SQL
SELECT
[Extent1].[GradeId] AS [GradeId],
[Extent1].[GradeName] AS [GradeName],
[Extent1].[Remark] AS [Remark]
FROM [dbo].[Grade] AS [Extent1]
3) 执行结果

4) 分析
1. 可见,以对象集合关联查询,生成的查询 SQL 中并没有任何 where 条件。
2. 首先查询所有的“右表数据”,再在程序中进行过滤。
3. 注意:这种关联查询并不是一种标准查询,并且对象集合必须为左表(t1的位置)。否则将抛出异常:System.NotSupportedException,无法创建“EFDBFirst6_0.Class1”类型的常量值。此上下文仅支持基元类型或枚举类型。
4. 最后,不推荐使用该方式连接查询,影响正常思维和效率。
深入理解 LINQ to SQL 生成的 SQL 语句的更多相关文章
- 查看Linq to Sql生成的sql语句(转)
查看Linq to Sql生成的sql语句 在控制台项目中,比较简单,直接db.Log = Console.Out;就OK了 但是在其他项目中,需要处理如下: StreamWriter sw = ...
- SqlProfilter监控指定数据库数据表——监控linq组合查询生成的sql
1.例子 实际测试环境中往往很多测试都在调用数据库,那么如何使用SqlProfilter监控筛选到自己想要监看的数据库对应的表有关linq生成的sql时候就需要做如下设置了 ........... u ...
- netcore sqlserver linq contains生成的sql语句不是使用like而是charIndex
在ef中使用linq调用了contains,结果怎么都查不到值,打开sqlserver profiler 发现生成的sql语句不是使用like...而是CharIndex 参考文档:https://s ...
- Linq To EF 用泛型时生成的Sql会查询全表的问题
1.问题的现象 public class LinqHepler<T> where T:class { private EFDBContext _context = null; /// &l ...
- 简单理解ORM,实体类生成查询SQL语句
目前有很多开源的ORM项目,大多情况下也不需要我们重复去造轮子,我们只需要了解轮子怎么造的,怎么用就可以,下面简单说一下怎么通过实体生成一个SQL语句: 先建立2个Attribute类,TableAt ...
- Rafy 领域实体框架设计 - 重构 ORM 中的 Sql 生成
前言 Rafy 领域实体框架作为一个使用领域驱动设计作为指导思想的开发框架,必然要处理领域实体到数据库表之间的映射,即包含了 ORM 的功能.由于在 09 年最初设计时,ORM 部分的设计并不是最重要 ...
- 用LinqPad查看Nhibernate生成的sql语句
使用Nhibernate开发一般都要对Nhibernate生成的sql语句进行查看及分析,查看Nhibernate生成的sql语句,可以使用NHProfiler和log4net.但NHProfiler ...
- 使用工具追踪Entity Framework生成的SQL
学习entity framework期间收集的文章,转自http://www.cnblogs.com/hiteddy/archive/2011/10/01/Difference_among_IQuer ...
- EF查询生成的SQL
在EF 4和EF 3.5 SP1中,我们可以使用ToTraceString()方法得到EF查询所生成的SQL. using (var context = new TestDBEntities()) { ...
随机推荐
- eclipse弃坑记第一篇之在idea上配置Tomcat环境并创建Javaweb项目的详细步骤原创
IntelliJ IDEA是一款功能强大的开发工具,在代码自动提示.重构.J2EE支持.各类版本工具(如git.svn.github).maven等方面都有很好的应用. IntelliJ IDEA有免 ...
- Python 函数初识 (1)
一.今日主要内容 认识函数 函数:对功能或者动作的封装(定义) 语法: def 函数名字(形参) 函数体 函数的调用格式:函数名(实参) 函数的返回值 关键字:return 终止函数的运行 1.函数内 ...
- audio元素和video元素在ios和andriod中无法自动播放
原因: 因为各大浏览器都为了节省流量,做出了优化,在用户没有行为动作时(交互)不予许自动播放: /音频,写法一 <audio src="music/bg.mp3" autop ...
- Pyqt5-Python应用开发——第一个小程序的实现
环境:python 3.6.6 编辑器:pycharm 其他:QtDesigner:Qt Designer,是一个直观可见的全方位 GUI 构造器,它所设计出来的用户界面能够在多种平台上使用.它是 Q ...
- 使用sz/rz基于串口传输文件
关键词:lrzsz.minicom.ZMODEM.MD5sum等. 在环境受限的嵌入式系统上,往往只有串口可以使用. 此时如果需要传输文件,需要借助rz/sz工具,可以使用的传输协议有ZMODEM.Y ...
- flask(二)之Jinja2模板与Flask-WTF
01-文档 官方文档:http://docs.jinkan.org/docs/jinja2/ 02-基本语义 Jinja2做构成的模板文件中,文本内容大致可以分成几个种类.比如特殊文本(不进行转义,比 ...
- java常识
什么是java语言? java语言是美国Sun公司,在1995年推出的高级编程语言.所谓编程语言,是计算机的语言,人们可以使用编程语言对计算机下达命令,让计算机完成人们需要的功能. java语言发展历 ...
- 周末学习笔记——day01(函数,函数对象,嵌套调用,名称空间,作用域,闭包,装饰器)
一,复习 字符编码 文件头:py2—ASCII,py3—UTF-8 三种字符串:u' ' b ' ' r ' ' u' ' .endcode(' utf-8 ') b' '.deconde(' utf ...
- Winform数据库连接app.config文件配置
1.添加配置文件 新建一个winform应用程序,类似webfrom下有个web.config,winform下也有个App.config;不过 App.config不是自动生成的需要手动添加,鼠标右 ...
- MySQL的运算符及其优先级
+++++++++++++++++++++++++++++++++++++++++++标题:MySQL的常见运算符时间:2019年2月23日内容:MySQL的常见运算符重点:主要讲述MySQL常见运算 ...