gpt4 book ai didi

linq 样式,链接 where 子句与和运算符

转载 作者:行者123 更新时间:2023-12-04 00:36:34 26 4
gpt4 key购买 nike

写作是否有(逻辑/性能)差异:
ATable.Where(x=> condition1 && condition2 && condition3)
或者
ATable.Where(x=>condition1).Where(x=>condition2).Where(x=>condition3)
我一直在使用前者,但意识到使用后者,我可以读取和复制部分查询,以便在其他地方更轻松地使用。
有什么想法吗?

最佳答案

简答
您应该在您的应用程序中做您认为更具可读性和可维护性的事情,因为两者都将评估为同一个集合。

长答案相当长

Linq 到对象 ATable.Where(x=> condition1 && condition2 && condition3)对于这个例子,由于只有一个谓词语句,编译器只需要生成一个委托(delegate)和一个编译器生成的方法。
从反射器

if (CS$<>9__CachedAnonymousMethodDelegate4 == null)
{
CS$<>9__CachedAnonymousMethodDelegate4 = new Func<ATable, bool>(null, (IntPtr) <Main>b__0);
}
Enumerable.Where<ATable>(tables, CS$<>9__CachedAnonymousMethodDelegate4).ToList<ATable>();

编译器生成方法:
[CompilerGenerated]
private static bool <Main>b__0(ATable m)
{
return ((m.Prop1 && m.Prop2) && m.Prop3);
}

如您所见,只有一次调用 Enumerable.Where<T>由于只有一个 Where,因此与委托(delegate)符合预期扩展方法。
ATable.Where(x=>condition1).Where(x=>condition2).Where(x=>condition3)现在对于这个例子,生成了更多的代码。
    if (CS$<>9__CachedAnonymousMethodDelegate5 == null)
{
CS$<>9__CachedAnonymousMethodDelegate5 = new Func<ATable, bool>(null, (IntPtr) <Main>b__1);
}
if (CS$<>9__CachedAnonymousMethodDelegate6 == null)
{
CS$<>9__CachedAnonymousMethodDelegate6 = new Func<ATable, bool>(null, (IntPtr) <Main>b__2);
}
if (CS$<>9__CachedAnonymousMethodDelegate7 == null)
{
CS$<>9__CachedAnonymousMethodDelegate7 = new Func<ATable, bool>(null, (IntPtr) <Main>b__3);
}
Enumerable.Where<ATable>(Enumerable.Where<ATable>(Enumerable.Where<ATable>(tables, CS$<>9__CachedAnonymousMethodDelegate5), CS$<>9__CachedAnonymousMethodDelegate6), CS$<>9__CachedAnonymousMethodDelegate7).ToList<ATable>();

由于我们有三个链式扩展方法,我们也得到三个 Func<T> s 以及三个编译器生成的方法。
[CompilerGenerated]
private static bool <Main>b__1(ATable m)
{
return m.Prop1;
}

[CompilerGenerated]
private static bool <Main>b__2(ATable m)
{
return m.Prop2;
}

[CompilerGenerated]
private static bool <Main>b__3(ATable m)
{
return m.Prop3;
}

现在看起来这应该更慢,因为有更多的代码。然而,由于所有执行都推迟到 GetEnumerator()被称为我怀疑任何明显的差异都会出现。

一些可能影响性能的陷阱
  • 在链中对 GetEnumerator 的任何调用都会导致集合被迭代。 ATable.Where().ToList().Where().ToList()ToList 时,将导致集合与第一个谓词的迭代。被调用,然后使用第二个 ToList 进行另一个迭代.尝试将 GetEnumerator 调用保持在最后一刻,以减少迭代集合的次数。

  • Linq 到实体
    由于我们使用 IQueryable<T>现在我们的编译器生成的代码有点不同,因为我们使用的是 Expresssion<Func<T, bool>>而不是我们正常的 Func<T, bool>
    合而为一的例子。 var allInOneWhere = entityFrameworkEntities.MovieSets.Where(m => m.Name == "The Matrix" && m.Id == 10 && m.GenreType_Value == 3);
    这会产生一个声明。
    IQueryable<MovieSet> allInOneWhere = Queryable.Where<MovieSet>(entityFrameworkEntities.MovieSets, Expression.Lambda<Func<MovieSet, bool>>(Expression.AndAlso(Expression.AndAlso(Expression.Equal(Expression.Property(CS$0$0000 = Expression.Parameter(typeof(MovieSet), "m"), (MethodInfo) methodof(MovieSet.get_Name)), ..tons more stuff...ParameterExpression[] { CS$0$0000 }));
    最值得注意的是,我们最终得到一棵表达式树,它被解析为 Expression.AndAlso。件。而且正如预期的那样,我们只有一个电话给 Queryable.Where var chainedWhere = entityFrameworkEntities.MovieSets.Where(m => m.Name == "The Matrix").Where(m => m.Id == 10).Where(m => m.GenreType_Value == 3);
    我什至不会为此费心粘贴编译器代码,太长了。但简而言之,我们最终会收到三个对 Queryable.Where(Queryable.Where(Queryable.Where())) 的调用。和三个表达式。这又是预料之中的,因为我们有三个链式 Where条款。

    生成的 Sql
    点赞 IEnumerable<T> IQueryable<T>在调用枚举器之前也不会执行。正因为如此,我们很高兴知道两者都产生了完全相同的 sql 语句:
    SELECT 
    [Extent1].[AtStore_Id] AS [AtStore_Id],
    [Extent1].[GenreType_Value] AS [GenreType_Value],
    [Extent1].[Id] AS [Id],
    [Extent1].[Name] AS [Name]
    FROM [dbo].[MovieSet] AS [Extent1]
    WHERE (N'The Matrix' = [Extent1].[Name]) AND (10 = [Extent1].[Id]) AND (3 = [Extent1].[GenreType_Value])

    一些可能影响性能的陷阱
  • 链中对 GetEnumerator 的任何调用都会导致对 sql 的调用,例如ATable.Where().ToList().Where()实际上将查询 sql 以查找与第一个谓词匹配的所有记录,然后使用 linq 将列表过滤为具有第二个谓词的对象。
  • 既然您提到提取谓词以在 else where 中使用,请制作 确定 它们的格式为 Expression<Func<T, bool>>而不仅仅是Func<T, bool> .第一个可以解析成表达式树并转化为有效的sql,第二个会触发所有对象返回和 Func<T, bool>将在该集合上执行。

  • 我希望这对回答你的问题有点帮助。

    关于linq 样式,链接 where 子句与和运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5188780/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com