前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于linq语句得一些隐藏bug分析

关于linq语句得一些隐藏bug分析

作者头像
易兒善
发布2019-01-03 15:18:55
4060
发布2019-01-03 15:18:55
举报
文章被收录于专栏:挖坑填坑

Contains

代码语言:javascript
复制
table.Where(m=>datas.Contains (m=>m.Id)) 

上面得这段代码换转换成类似下面这样得sql

代码语言:javascript
复制
select * from table where Id in (...datas)

看上去没问题,通常使用情况下也是没有问题。突然有一天数据库返回一个错误,说你得查询语句太复杂了,然你优化。这时候你就要检查一下datas得长度。有人说是1000,有人说是转换后1000个字节得长度。反正数据库就是罢工了。

委托

这样定义一个委托。

代码语言:javascript
复制
        public bool Any(Func<Storage, bool> predicate) {
            return _storageRepository.GetAll().Any(predicate);
        }

然后这样调用。

代码语言:javascript
复制
 _service.Any(m => m.UserId == 123);

本身没有什么问题。当Storage这张表数据量较少时也没什么问题。当数据量在几十万,几百万时,发现上面语句执行得很慢,甚至得不到结果而超时。 与直接调用以下语句并不是一回事。

代码语言:javascript
复制
_storageRepository.GetAll().Any(m => m.UserId == 123);

list多条件查询

代码语言:javascript
复制
            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

代码语言:javascript
复制
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语句

代码语言:javascript
复制
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中,数据量大的情况下,很有可能超时查不出数据来。 建议修改为,效率是完全不一样的。

代码语言:javascript
复制
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)
     
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.12.29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Contains
  • 委托
  • list多条件查询
  • FirstOrDefault
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档