美文网首页一步一坑
关于linq语句得一些隐藏bug分析

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

作者: 易兒善 | 来源:发表于2018-12-29 18:20 被阅读28次

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)
     
}

相关文章

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

    Contains 上面得这段代码换转换成类似下面这样得sql 看上去没问题,通常使用情况下也是没有问题。突然有一天...

  • LINQ语句

    //查询表达式概述//1.查询表达式用于查询并转换所有启用LINQ的数据源的数据。例如:通过一个查询即可检索sql...

  • linq语句

    https://www.yiibai.com/linq/linq_filtering_operators.html...

  • Linq语句

    var result = students.Where(x => x.Sex.Equals("男") && x.A...

  • Linq语句初接触

    在unity中简单的使用Linq语句

  • AndroidStudio调试之旅

    ​ 在平常开发中难免会写出一些bug,明显的bug通过分析代码可以找出来问题所在,但也会有一些隐藏很深的bu...

  • Language Integrated Query(LINQ,语

    第一次接触到Linq很开心 Linq 有两种写法,一种是 语句,另一种是^表达式 linq用来遍历集合很方便,和f...

  • C#日记——强大的查询LINQ

    LINQ——语言集成查询(Language Integrated Query),是一个用来查询数据的语句,不仅可以...

  • 语句积累

    非常见的增删改查语句之外的一些语句 1. 查询分析 执行查询分析只需要在分析语句前面加上explain关键字就好 ...

  • LINQ

    什么是linq? linq是语言集成查询。 linq主要包含三部分 linq to xml linq to obj...

网友评论

    本文标题:关于linq语句得一些隐藏bug分析

    本文链接:https://www.haomeiwen.com/subject/ceqikqtx.html