Linq to objects - 笨蛋?
Linq to objects - boondoggle?
我认为 LINQ to objects 是不同执行连接数据的好方法。实际上,它是一种糟糕的做事方式...
这是我们有的,在a,b,c,d
中相应地有几、几百、3K和3.5K条记录
IEnumerable<MyModel> data =
(from a in AList
from b in BList.Where(r => r.AId == a.Id)
from c in CList.Where(r => r.BId == b.Id)
from d in DList.Where(r => r.SomeId == myId && r.Some2Id == c.Some2Id)
// . . . . . .
LINQ 难道不应该很擅长做这件事吗?
实际上,跟随的速度要快得多,实际上快 60 倍
var dTemp = DList.Where(r => r.SomeId == myId).ToList();
var cTemp = CList.Where(c => dTemp.Any(d => d.Some2Id == c.Some2Id)).ToList();
IEnumerable<MyModel> data =
(from a in AList
from b in BList.Where(r => r.AId == a.Id)
from c in cTemp.Where(r => r.BId == b.Id)
// . . . . . .
然后我遇到了this article
问:有没有办法在不放弃单个 LINQ 的情况下改进此查询?
或者这是否意味着如果性能受到威胁,需要避免使用 LINQ to objects in joins 并替换为一些顺序调用?
我们来分析一下差异。
第一个查询:您在 BList
上执行一个过滤器,在 CList
上执行一个过滤器,在 DList
上执行两个过滤器,全部在延迟执行的方式。然后您使用一种连接。
第二个查询:您在 DList
上执行静态过滤器并对其进行评估,在 CList
上基于 DList
执行另一个静态过滤器并对其进行评估,然后AList
和 BList
.
上的延迟执行过滤器
第二个查询更快,因为:
DList
未被视为无用值(由于之前的过滤器)
CList
由于之前的过滤器 只包含有用的值
无论如何,这两个查询都是错误的。多个from
基本上就是一个cross-join
、as explained here。正如@Reddog 评论的那样,最好的方法是实际使用 Join
:
var data = from a in AList
join b in BList on a.Id equals b.AId
join c in CList on b.Id equals c.BId
join d in DList on c.Some2Id equals d.Some2Id
where d.SomeId == someId;
我认为 LINQ to objects 是不同执行连接数据的好方法。实际上,它是一种糟糕的做事方式...
这是我们有的,在a,b,c,d
中相应地有几、几百、3K和3.5K条记录
IEnumerable<MyModel> data =
(from a in AList
from b in BList.Where(r => r.AId == a.Id)
from c in CList.Where(r => r.BId == b.Id)
from d in DList.Where(r => r.SomeId == myId && r.Some2Id == c.Some2Id)
// . . . . . .
LINQ 难道不应该很擅长做这件事吗? 实际上,跟随的速度要快得多,实际上快 60 倍
var dTemp = DList.Where(r => r.SomeId == myId).ToList();
var cTemp = CList.Where(c => dTemp.Any(d => d.Some2Id == c.Some2Id)).ToList();
IEnumerable<MyModel> data =
(from a in AList
from b in BList.Where(r => r.AId == a.Id)
from c in cTemp.Where(r => r.BId == b.Id)
// . . . . . .
然后我遇到了this article
问:有没有办法在不放弃单个 LINQ 的情况下改进此查询?
或者这是否意味着如果性能受到威胁,需要避免使用 LINQ to objects in joins 并替换为一些顺序调用?
我们来分析一下差异。
第一个查询:您在 BList
上执行一个过滤器,在 CList
上执行一个过滤器,在 DList
上执行两个过滤器,全部在延迟执行的方式。然后您使用一种连接。
第二个查询:您在 DList
上执行静态过滤器并对其进行评估,在 CList
上基于 DList
执行另一个静态过滤器并对其进行评估,然后AList
和 BList
.
第二个查询更快,因为:
DList
未被视为无用值(由于之前的过滤器)CList
由于之前的过滤器 只包含有用的值
无论如何,这两个查询都是错误的。多个from
基本上就是一个cross-join
、as explained here。正如@Reddog 评论的那样,最好的方法是实际使用 Join
:
var data = from a in AList
join b in BList on a.Id equals b.AId
join c in CList on b.Id equals c.BId
join d in DList on c.Some2Id equals d.Some2Id
where d.SomeId == someId;