无法将 SQL 查询转换为左外连接的 LINQ 查询
Unable to convert SQL Query to LINQ Query for Left Outer Join
问题陈述:
我正在尝试将我的 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 中获得像 Sql 这样的查询吗?
资产标签table:
问题table:
Return table:
期望输出:
您需要删除 .AsEnumerable()
,因为您希望将查询翻译成 sql
。现在它将使用 linq-to-objects
,如果您使用带有 linq-to-object
的左连接,您需要检查空引用异常。 rt
可能为空,因此 rt.RequestStatus
会抛出异常。
*我相信 rt
在你的例子中应该是 r
您无法投影到现有实体,因此您需要将 select 更改为:
select new PocoClass
{
model1=at
}
//New class definition
public PocoClass
{
public AssetTagging model1 { get; set; }
}
尝试以下操作我假设您仍然想要 r 为空的情况,除非 r 不为空并且请求状态 = 已批准。
在检查请求状态之前,您必须检查以验证 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();
这是完整的查询
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();
您需要这样做:
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();
尝试如下:
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"
做两次left outer join然后在where条件下做过滤
也先看看 this msdn 关于使用 linq 进行左外连接的文章。
我知道这不是您所要求的,但它可能还是有用的。
如果您有权访问数据库以执行 SQL 查询,我建议创建一个视图。然后,您可以像使用 table 一样将视图放入 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')
问题陈述:
我正在尝试将我的 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 中获得像 Sql 这样的查询吗?
资产标签table:
问题table:
Return table:
期望输出:
您需要删除 .AsEnumerable()
,因为您希望将查询翻译成 sql
。现在它将使用 linq-to-objects
,如果您使用带有 linq-to-object
的左连接,您需要检查空引用异常。 rt
可能为空,因此 rt.RequestStatus
会抛出异常。
*我相信 rt
在你的例子中应该是 r
您无法投影到现有实体,因此您需要将 select 更改为:
select new PocoClass
{
model1=at
}
//New class definition
public PocoClass
{
public AssetTagging model1 { get; set; }
}
尝试以下操作我假设您仍然想要 r 为空的情况,除非 r 不为空并且请求状态 = 已批准。
在检查请求状态之前,您必须检查以验证 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();
这是完整的查询
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();
您需要这样做:
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();
尝试如下:
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"
做两次left outer join然后在where条件下做过滤
也先看看 this msdn 关于使用 linq 进行左外连接的文章。
我知道这不是您所要求的,但它可能还是有用的。
如果您有权访问数据库以执行 SQL 查询,我建议创建一个视图。然后,您可以像使用 table 一样将视图放入 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')