AJ.*_*AJ. 8 linq vb.net linq-to-entities left-join
我有一个heckuva时间弄清楚如何将带有两个条件where子句的简单SQL LEFT OUTER JOIN转换为一个有效的Linq-to-Entities查询.只有两张桌子.我需要Table1中所有行的值,无论Table2中的匹配如何,但WHERE子句使用Table2中的字段.在SQL中,两个参数是Table2WhereColumn1和Table2WhereColumn2,查询(可以工作)如下所示:
SELECT t1.Table1Id,
t1.FieldDescription,
t2.FieldValue
FROM Table1 t1 WITH (NOLOCK)
LEFT JOIN Table2 t2 WITH (NOLOCK) ON t1.Table1Id = t2.Table1Id
WHERE (t2.Table2WhereColumn1 = @someId OR t2.Table2WhereColumn1 IS NULL)
AND (t2.Table2WhereColumn2 = @someOtherId OR t2.Table2WhereColumn2 IS NULL)
ORDER BY t1.OrderByColumn
Run Code Online (Sandbox Code Playgroud)
我尝试过使用Group Joinwith DefaultIfEmpty(),以及一个隐式连接(没有实际的Join关键字),我只获得表2中具有值的项的行.我相信这不会有帮助,但是这里有一个我一直在尝试的Linq的例子不起作用:
Public Shared Function GetProfilePreferencesForCedent(ByVal dc As EntityContext, _
ByVal where1 As Int32, _
ByVal where2 As Int32) _
As IQueryable(Of ProjectedEntity)
Return From t1 In dc.Table1
Group Join t2 In dc.Table2 _
On t1.Table1Id Equals t2.Table1Id _
Into t2g1 = Group _
From t2gx In t2g1.DefaultIfEmpty(Nothing)
Where (t2gx.Table2Where1 = where1 Or t2gx.Table2Where1 = Nothing) _
And (t2gx.Table2Where2 = where2 Or t2gx.Table2Where2 = Nothing)
Order By t1.SortOrder
Select New ProjectedEntity With {
.Table1Id = t1.Table1Id, _
.FieldDescription = t1.FieldDescription, _
.FieldValue = If(t2gx Is Nothing, String.Empty, t2gx.FieldValue) _
}
End Function
Run Code Online (Sandbox Code Playgroud)
Eni*_*ity 12
请查看这些查询并告诉我它们是否适合您.我没有设置要测试的数据,但它们应该没问题.
请原谅我的C#和VB.NET的混合.我曾经是一名VB.NET开发人员,但在过去的几年里,我主要在C#工作,所以我现在感觉更舒服.
这是我为Table1&创建的类Table2:
public class Table1
{
public int Table1Id { get; set; }
public string FieldDescription { get; set; }
public int OrderByColumn { get; set; }
}
public class Table2
{
public int Table1Id { get; set; }
public string FieldValue { get; set; }
public int Table2WhereColumn1 { get; set; }
public int Table2WhereColumn2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在C#中的查询应该是:
var query =
from t1 in Table1
join t2 in Table2 on t1.Table1Id equals t2.Table1Id into _Table2
from _t2 in _Table2.DefaultIfEmpty()
where _t2 == null ? true :
_t2.Table2WhereColumn1 == @someId
&& _t2.Table2WhereColumn2 == @someOtherId
orderby t1.OrderByColumn
select new
{
t1.Table1Id,
t1.FieldDescription,
FieldValue = _t2 == null ? "" : _t2.FieldValue,
};
Run Code Online (Sandbox Code Playgroud)
并转换成VB.NET:
Dim query = _
From t1 In Table1 _
Group Join t2 In Table2 On t1.Table1Id Equals t2.Table1Id Into _Table2 = Group _
From _t2 In _Table2.DefaultIfEmpty() _
Where If(_t2 Is Nothing, True, _t2.Table2WhereColumn1 = someId AndAlso _
_t2.Table2WhereColumn2 = someOtherId) _
Order By t1.OrderByColumn _
Select New With { _
.Table1Id = t1.Table1Id, _
.FieldDescription = t1.FieldDescription, _
.FieldValue = If(_t2 Is Nothing, "", _t2.FieldValue) _
}
Run Code Online (Sandbox Code Playgroud)
如果他们有效,请告诉我.手指交叉.:-)
就我个人而言,如果左连接的右侧有 where 条件,我通常更喜欢将它们放入连接标准中
在这种情况下,SQL 将如下所示:
SELECT t1.Table1Id,
t1.FieldDescription,
t2.FieldValue
FROM Table1 t1 WITH (NOLOCK)
LEFT JOIN Table2 t2 WITH (NOLOCK) ON t1.Table1Id = t2.Table1Id
AND t2.Table2WhereColumn1 = @someId
AND t2.Table2WhereColumn2 = @someOtherId
ORDER BY t1.OrderByColumn
Run Code Online (Sandbox Code Playgroud)
其 LINQ 代码(C# 语言)如下所示:
var query =
from t1 in Table1
join t2 in Table2 on new{a = t1.Table1Id, b = someId, c = someotherId}
equals new {a = t2.Table1Id b = t2.Table2WhereColumn1, c = Table2WhereColumn2}
into _Table2
from _t2 in _Table2.DefaultIfEmpty()
orderby t1.OrderByColumn
select new
{
t1.Table1Id,
t1.FieldDescription,
FieldValue = _t2 == null ? "" : _t2.FieldValue,
};
Run Code Online (Sandbox Code Playgroud)
没有测试过 - 但应该可以