无法将SQL查询转换为左外连接的LINQ查询

时间:2015-02-06 14:27:27

标签: sql asp.net-mvc linq

问题陈述:

我试图将我的一个Sql转换为linq查询,但我无法获得所需的输出。有谁能建议我应该做什么?

SQL查询:

SELECT AssetTagging.AssetID, AssetTagging.AssetDescription, [Return].RequestStatus
FROM  AssetTagging
LEFT OUTER JOIN [Return] ON AssetTagging.AssetID = [Return].AssetID
LEFT OUTER JOIN Issue ON AssetTagging.AssetID = Issue.AssetID
WHERE (Issue.AssetID IS NULL) OR ([Return].RequestStatus = 'Approved')

Linq查询我使用:

var result = (from at in db.AssetTagging.AsEnumerable()
                  join r in db.Return on at.AssetID equals r.AssetID
                  orderby at.AssetID
                  where !db.Issue.Any(issue=>issue.AssetID==at.AssetID) || r.RequestStatus=="Approved"
                  select new globalTestModel
                  {
                    model1=at
                  }).ToList();


//I know that in Linq query I'm using Inner join instead of Left Join,but i'm getting error if i use left join instead of inner join?

我做错了什么?

有任何关于在Linq中获得所需查询的建议吗?

资产标签表:

enter image description here

问题表:

enter image description here

返回表格

enter image description here

期望输出:

enter image description here

6 个答案:

答案 0 :(得分:2)

您需要删除.AsEnumerable(),因为您希望将查询翻译为sql。现在它将使用linq-to-objects,如果您使用linq-to-object的左连接,则需要检查空引用异常。 <{1}}可能为null,因此rt会抛出异常。

*我认为rt.RequestStatus在您的示例中应为rt

您无法投射到现有实体,因此您需要将您的选择更改为:

r

答案 1 :(得分:1)

尝试以下我假设您仍然希望r为空的情况,除非r不为null且请求状态=已批准。

在检查请求状态之前,您必须检查以验证r!= null,并且当r为null时仍需要包含以获取完整的结果集。我没有对此进行过测试,但这应该会让你朝着正确的方向前进。

祝你好运。

  var result = (from at in db.AssetTagging
               join r in db.Return.DefaultIfEmpty()
               on at.AssetID equals r.AssetID
               join i in db.Issue.DefaultIfEmpty()
               on  at.AssetID equals i.AssetID
               where 
               (r == null || (r!=null && r.RequestStatus == "Approved"))
               || i == null
               select new {
                at.AssetID,
                at.AssetDescription,
                IssueID = (i!=null) ? i.IssueID : null),
                ReturnID = (r!=null) ? r.ReturnID: null),
                ReturnStatus = (r!=null) 
                     ? r.ReturnStatus 
                     : null}).ToList();

答案 2 :(得分:1)

你需要这样做:

 var result = from at in db.AssetTagging
              join r in db.Returns on at.AssetID equals r.AssetID into a
              from returns into a.DefaultIfEmpty()
              join i in db.Issues on at.AssetID equals I.AssetID into b
              from issues into b.DefaultIfEmpty()
              where issues.AssetID != null || returns.RequestStatus == "Approved"
              select new
                    {
                      AssetID = at.AssetID,
                      AssetDescription = at.AssetDescription,
                      Status = returns != null ? returns.RequestStatus : null
                    }.ToList();

答案 3 :(得分:1)

尝试如下:

from at in db.AssetTagging
join r in db.Return on at.AssetID equals r.AssetID into res1
from atr in res1.DefaultIfEmpty()
join  i in db.Issues on i.AssetID==at.AssetID into res2
from obj in res2.DefaultIfEmpty()
select at
where i.AssetID == null || r.RequestStatus equals "Approved"

只需做两次左外连接,然后对条件进行过滤。

首先查看this msdn关于使用linq的左外连接的文章。

答案 4 :(得分:1)

我知道这并不是你要求的,但无论如何它可能都有用。

如果您有权访问数据库以执行SQL查询,我建议您创建一个视图。然后,您可以像使用表一样将视图放入DBML文件中,并在C#代码中使用更简单的Linq表达式。

CREATE VIEW [Asset_Issue_Return_Joined] AS
SELECT AssetTagging.AssetID, AssetTagging.AssetDescription, [Return].RequestStatus
FROM  AssetTagging
LEFT OUTER JOIN [Return] ON AssetTagging.AssetID = [Return].AssetID
LEFT OUTER JOIN Issue ON AssetTagging.AssetID = Issue.AssetID
WHERE (Issue.AssetID IS NULL) OR ([Return].RequestStatus = 'Approved')

答案 5 :(得分:0)

这是完整的查询

  var result = (from assetTagging in db.AssetTagging
                join return0 in db.Return on assetTagging.AssetID equals return0.AssetID into returns
                from return0 in returns.DefaultIfEmpty()
                join issue in db.Issue on assetTagging.AssetID equals issue.AssetID into issues
                from issue in issues.DefaultIfEmpty()
                where issue.AssetID == null || return0.RequestStatus == "Approved"
                select new
                {
                   assetTagging.AssetID,
                   assetTagging.AssetDescription,
                   return0.RequestStatus
                }).ToList();