代码之家  ›  专栏  ›  技术社区  ›  Zachary Scott

如何在linq to实体中执行SQL“where exists”?

  •  23
  • Zachary Scott  · 技术社区  · 14 年前

    我真的想这样做:

    Select * 
    from A join B on A.key = B.key join C on B.key = C.key -- propagated keys
    where exists (select null from B where A.key = B.key and B.Name = "Joe") and
          exists (select null from C where B.key = C.key and C.Name = "Kim")
    

    使用Entity Framework 4和C_,LINQ语句会是什么样子?

    更新:

    显然,contains()将生成“where exists”结果。所以,又一次尝试
    (我不知道这是否会编译LOL):

    var inner1 = from recordB in B
                 where recordB.Name = "Joe"
                 select recordB.key;
    
    var inner2 = from recordC in C
                 where recordC.Name = "Kim"
                 select recordC.key;
    
    var result = from recordA in A
                 where inner1.Contains( recordA.key) &&
                       inner2.Contains( recordA.key)
                 select recordA;
    

    编辑:哇,这才是真正有效的方法:

    var result = from A in Products
                 where A.kfield1 == 1 && A.kfield2 == 2 &&
                       ( from B in Btable
                         where B.otherid == "Joe" &&  // field I want to select by
                               B.kfield1 == A.kfield1 &&     
                               B.kfield2 == A.kfield2 // Can keep adding keys here
                         select A.identifier  // unique identity field 
                       ).Contains(A.identifier) &&
                       ( from C in Ctable
                         where C.otherid == "Kim" &&  // field I want to select by
                               C.kfield1 == A.kfield1 &&     
                               C.kfield2 == A.kfield2 // Can keep adding keys here
                         select A.identifier  // unique identity field 
                       ).Contains(A.identifier)
                 select A;
    

    这产生了这个SQL:

    SELECT [t0].[identifier], [t0].*
    FROM [A] AS [t0]
    WHERE ([t0].[kfield1] = @p0) AND ([t0].[kfield2] = @p1) AND (EXISTS(
        SELECT NULL AS [EMPTY]
        FROM [B] AS [t1]
        WHERE ([t0].[identifier] = [t0].[identifier]) AND ([t1].[otherid] = @p2) AND
              ([t1].[kfield1] = [t0].[kfield1]) AND 
              ([t1].[kfield2] = [t0].[kfield2]))) AND (EXISTS(
        SELECT NULL AS [EMPTY]
        FROM [C] AS [t2]
        WHERE ([t0].[identifier] = [t0].[identifier]) AND ([t2].[otherid] = @p3) AND
              ([t2].[kfield1] = [t0].[kfield1]) AND 
              ([t2].[kfiekd2] = [t0].[kfield2]) ))
    

    这就是我想要的。请注意[t0]。[identifier]=[t0]。[identifier],它筛选出空值,因为空值与包括自身在内的任何内容(在SQL中)都不相等。

    2 回复  |  直到 14 年前
        1
  •  34
  •   David Pfeffer    14 年前

    这个 .Any() 扩展方法通常映射到 exists .

        2
  •  0
  •   AJ.    14 年前

    您是否尝试添加 exists 你加入的条件?

    from a in context.AEntity
    Join B in context.BEntity on A.Key equals B.Key && B.Name == "Joe"
    Join C in context.CEntity on B.Key equals C.Key && C.Name == "Kim";
    

    不确定这是否可行,但值得一试。