LINQ to SQL Right Outer Join

时间:2014-07-03 21:27:18

标签: c# linq outer-join

我有一个SQL查询,我无法转换为LINQ查询:

SELECT DISTINCT Nodes.NodeName, NodeConfig.IPAddresses, NodeConfig.InSCOM, NodeConfig.InOrion, NodeConfig.OrionCustomerName, NodeConfig.OrionApplication, NodeConfig.NodeID
FROM            Tags INNER JOIN
                     TagToNode ON Tags.TagID = TagToNode.TagID RIGHT OUTER JOIN
                     NodeConfig INNER JOIN
                     Nodes ON NodeConfig.NodeID = Nodes.NodeID ON TagToNode.NodeID = NodeConfig.NodeID
WHERE        (NodeConfig.Session = '7/3/2014 1:46:33 PM') AND (NodeConfig.InSCOM = 0)

返回1076行。

我试着编写LINQ等价物:

var list1 = (from t in mldb.Tags
                    join tn in mldb.TagToNodes on t.TagID equals tn.TagID into tagJoin
                    from tj in tagJoin.DefaultIfEmpty()
                    join nc in mldb.NodeConfigs on tj.NodeID equals nc.NodeID
                    join n in mldb.Nodes on nc.NodeID equals n.NodeID
                    where (nc.Session == @"7/3/2014 1:46:33 PM") && (nc.InSCOM == 0)
                    select new { Customer = nc.OrionCustomerName, DeviceName = n.NodeName, DeviceType = nc.OrionApplication, IPAddress = nc.IPAddresses, NodeID = n.NodeID }).Distinct().ToList();

返回183行。

我尝试将查询转换为内部联接,正如我在此站点上搜索解决方案时所建议的那样。原始查询实现了一个SQL“RIGHT OUTER JOIN”,它在LINQ中不支持我从左/右读过的内容,但是可以进行连接。

我从中拉出的表格主键如下:

[DataServiceKey(new string[] { "NodeID", "TagID" })]
public partial class TagToNode { }

[DataServiceKey(new string[] { "NodeID" })]
public partial class Node { }

[DataServiceKey(new string[] { "TagID" })]
public partial class Tag { }

[DataServiceKey(new string[] { "ConfigID" })]
public partial class NodeConfig { }

关系是节点有很多NodeConfigs,许多节点标记有很多标签。

有人可以帮我查询逻辑吗?

1 个答案:

答案 0 :(得分:0)

好的,我退后一步,重新构建了查询。我首先创建了一个内连接,然后将其连接到主查询。

我有一个数据库中的计算机列表,这些计算机被标记为"在我的申请中。我希望能够通过标签和设备之间的多对多关系来搜索数据库中的标签名称,其中我在中间有一个名为" TagToNode"的连接表。

独特的选择最终只是消除了欺骗,即使他们没有标记任何东西,也可以获得所有计算机(节点)。

LINQ

var tags = (from tn in mldb.TagToNodes
                        join t in mldb.Tags on tn.TagID equals t.TagID
                        select new { tn.TagID, tn.NodeID, t.TagName, t.AssocUser });
            return (from nc in mldb.NodeConfigs
                    join n in mldb.Nodes on nc.NodeID equals n.NodeID
                    join t in tags on n.NodeID equals t.NodeID into nj
                    from tg in nj.DefaultIfEmpty()
                    where nc.Session == sc.SessionName && n.NodeActive == 1 && ((tg.TagName.Contains(sc.SearchTerm) && (tg.AssocUser.Contains(windowsId) || (tg.AssocUser == null || tg.AssocUser == ""))) || (n.NodeName.Contains(sc.SearchTerm)) || (nc.OrionCustomerName.Contains(sc.SearchTerm)) || (nc.IPAddresses.Contains(sc.SearchTerm)))
                    select new NodeInfo { Customer = nc.OrionCustomerName, DeviceName = n.NodeName, DeviceType = nc.OrionApplication, IPAddress = nc.IPAddresses, NodeID = n.NodeID }).Distinct().ToList();