关于linq语句得一些隐藏bug分析
时间:2022-06-16
本文章向大家介绍关于linq语句得一些隐藏bug分析,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Contains
table.Where(m=>datas.Contains (m=>m.Id))
上面得这段代码换转换成类似下面这样得sql
select * from table where Id in (...datas)
看上去没问题,通常使用情况下也是没有问题。突然有一天数据库返回一个错误,说你得查询语句太复杂了,然你优化。这时候你就要检查一下datas得长度。有人说是1000,有人说是转换后1000个字节得长度。反正数据库就是罢工了。
委托
这样定义一个委托。
public bool Any(Func<Storage, bool> predicate) {
return _storageRepository.GetAll().Any(predicate);
}
然后这样调用。
_service.Any(m => m.UserId == 123);
本身没有什么问题。当Storage这张表数据量较少时也没什么问题。当数据量在几十万,几百万时,发现上面语句执行得很慢,甚至得不到结果而超时。 与直接调用以下语句并不是一回事。
_storageRepository.GetAll().Any(m => m.UserId == 123);
list多条件查询
var storages = StorageRepository.GetAll();
var result = from user in users
join storage in storages
on new{userId = user.Id, orgId = user.OrgId}
equals new {userId =storage.UserId, orgId = storage.OrgId }
where storage.Quantity>0
select storage ;
上面得语句同样在表storage数据量小得时候很方便查询,但是数据量大得情况下并不奏效了。因为时将storages得数据全部取到内存中做得比较。这种多条件查询可以添加 userId-OrgId 关键字进行查询。
FirstOrDefault
from c in Storages
group c by new {c.OrgId,c.ProductId} into gStorage
select new {
id = gStorage.FirstOrDefault().Id,
gStorage.Key.OrgId,
gStorage.Key.ProductId,
Quantity = gStorage.Sum(n => n.Quantity)
}
这样得linq 会转换成如下sql语句
SELECT (
SELECT [t3].[Id]
FROM (
SELECT TOP (1) [t2].[Id]
FROM [Storage] AS [t2]
WHERE ([t1].[OrgId] = [t2].[OrgId]) AND ([t1].[ProductId] = [t2].[ProductId])
) AS [t3]
) AS [id], [t1].[OrgId], [t1].[ProductId], [t1].[value] AS [Quantity]
FROM (
SELECT SUM([t0].[Quantity]) AS [value], [t0].[OrgId], [t0].[ProductId]
FROM [Storage] AS [t0]
GROUP BY [t0].[OrgId], [t0].[ProductId]
) AS [t1]
但是在很多情况下都不会这样转换。在复杂的linq中,数据量大的情况下,很有可能超时查不出数据来。 建议修改为,效率是完全不一样的。
from c in Storages
group c by new {c.OrgId,c.ProductId} into gStorage
select new {
id = gStorage.Min(n => n.Id),
gStorage.Key.OrgId,
gStorage.Key.ProductId,
Quantity = gStorage.Sum(n => n.Quantity)
}
- 谈谈分布式事务之三: System.Transactions事务详解[下篇]
- 当InternalsVisibleToAttribute特性遭遇"强签名"
- MyBatis-从查询昨天的数据说起
- WCF并发(Concurrency)的本质:同一个服务实例上下文(InstanceContext)同时处理多个服务调用请求
- Spring集成RabbitMQ-必须知道的几个概念
- Spring读书笔记——bean创建(上)
- 15:21爆出的小程序功能升级,你还要对小程序观望吗?
- 如何解决分布式系统中的跨时区问题[原理篇]
- 什么是区块链:块的结构
- Spring读书笔记——bean创建(下)
- 当区块链遇上传统行业 我们的生活和工作会改变吗?
- 如何设计开发好一个 HTTP API?
- [WCF权限控制]基于Windows用户组的授权方式[下篇]
- Spring读书笔记——bean解析
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法