C# LINQ左外部联接不工作(以示例为例)

C# LINQ左外部联接不工作(以示例为例),c#,linq,C#,Linq,我保留了在Oracle中正常工作的外部联接,但在转换为LINQ时无法工作。当通过LINQ执行时,我没有得到任何记录,因为对于搜索的用户,记录在T_PER_ADDL_ATRB中不存在 SQL SELECT P.* FROM T_PER P INNER JOIN T_PER_CMN_ATRB C ON C.PER_ID = P.PER_ID LEFT OUTER JOIN T_PER_ADDL_ATRB A22 ON A22.PER_CMN_ATRB_ID

我保留了在Oracle中正常工作的外部联接,但在转换为LINQ时无法工作。当通过LINQ执行时,我没有得到任何记录,因为对于搜索的用户,记录在T_PER_ADDL_ATRB中不存在

SQL

SELECT  P.*
FROM    T_PER P
        INNER  JOIN T_PER_CMN_ATRB C ON C.PER_ID = P.PER_ID 
        LEFT OUTER JOIN T_PER_ADDL_ATRB A22 ON A22.PER_CMN_ATRB_ID = C.PER_CMN_ATRB_ID
WHERE   A22.ADDL_ATRB_ID = 22
        AND (C.PER_LST_NM LIKE 'Chen%' or A22.ADDL_ATRB_VAL like 'Chen%');
SQL返回1条记录

LINQ

(from P in db.T_PER
join C in db.T_PER_CMN_ATRB on P.PER_ID equals C.PER_ID
join A22 in db.T_PER_ADDL_ATRB on C.PER_CMN_ATRB_ID equals A22.PER_CMN_ATRB_ID into A22_join
from A22 in A22_join.DefaultIfEmpty()
where
  A22.ADDL_ATRB_ID == 22 &&
  (C.PER_LST_NM.StartsWith("Chen") ||
  A22.ADDL_ATRB_VAL.StartsWith("Chen"))
select P).ToList()

LINQ返回0条记录

使用
Where
DefaultIfEmpty()
以便将条件添加到
左外部联接
子句中

(from P in db.T_PER
join C in db.T_PER_CMN_ATRB on P.PER_ID equals C.PER_ID
join A22 in db.T_PER_ADDL_ATRB on C.PER_CMN_ATRB_ID equals A22.PER_CMN_ATRB_ID into A22_join
from A22 in A22_join.Where(x => x.ADDL_ATRB_ID == 22).DefaultIfEmpty()
where 
  (C.PER_LST_NM.StartsWith("Konyayev") ||
    (A22 == null || (A22 != null && A22.ADDL_ATRB_VAL.StartsWith("Konyayev"))
    )
  )
select P).ToList()
公共静态IEnumerable LeftJoin(此IEnumerable源、IEnumerable内部、Func pk、Func fk、Func result)
{
IEnumerable_result=Enumerable.Empty();
_结果=源中的s
加入我的内心世界
关于pk(s)等于fk(i)到joinData
从joinData.DefaultIfEmpty()中的左侧开始
选择结果(s,左侧);
返回结果;
}  

您可以选择类似于以下内容的内容:

from p in db.TPER
join c in db.T_PER_CMN_ATRB on p.PER_ID equals c.PER_ID
join a22 in db.T_PER_ADDL_ATRB.Where(p=> p.ADDL_ATRB_ID == 22) on c.PER_ID equals a22.PER_CMN_ATRB_ID into a22_join
from a22table in a22_join.DefaultIfEmpty()
select new {
a22table.ADDL_ATRB_ID,
C.PER_LST_NM,
A22.ADDL_ATRB_VAL
P,
}).Where(p=> p.PER_LST_NM.StartsWith("Chen") || p.ADDL_ATRB_VAL.StartsWith("Chen")).ToList()

只要Oracle没有对您的SQL进行特殊转换,
其中A22.ADDL_ATRB_ID=22
基本上应该会终止
左外部连接。在加入之前尝试添加该条件,例如,
在db.T_PER_ADDL_ATRB.Where中加入A22(A22=>A22.ADDL_ATRB_ID==22)
并将其从
Where
子句中删除。您的SQL正在搜索Chen,但您的Linq使用的是Konyayev。这很有效,但性能很差。我猜是因为做了两个陈述而不是一个。
from p in db.TPER
join c in db.T_PER_CMN_ATRB on p.PER_ID equals c.PER_ID
join a22 in db.T_PER_ADDL_ATRB.Where(p=> p.ADDL_ATRB_ID == 22) on c.PER_ID equals a22.PER_CMN_ATRB_ID into a22_join
from a22table in a22_join.DefaultIfEmpty()
select new {
a22table.ADDL_ATRB_ID,
C.PER_LST_NM,
A22.ADDL_ATRB_VAL
P,
}).Where(p=> p.PER_LST_NM.StartsWith("Chen") || p.ADDL_ATRB_VAL.StartsWith("Chen")).ToList()