我有以下查询:
SELECT COUNT(1)
FROM Warehouse.WorkItems wi
WHERE wi.TaskId = (SELECT TaskId
FROM Warehouse.WorkItems
WHERE WorkItemId = @WorkItemId)
AND wi.IsComplete = 0;
由于我们使用EF,我希望能够使用Linq功能来生成此查询。 (我知道我可以给它一个像这样的字符串查询,但我想使用EF + Linq为我生成查询,因为重构原因。)
我真的不需要知道查询的结果。我只需要知道是否有任何结果。 (使用Any()
将是完美的,但我无法获得它的写代码。)
所以......基本上,我如何将该SQL查询编写为LINQ查询?
编辑:表格结构
WorkItemId - int - Primary Key
TaskId - int - Foreign Key on Warehouse.Tasks
IsComplete - bool
JobId - int
UserName - string
ReportName - string
ReportCriteria - string
ReportId - int - Foreign Key on Warehouse.Reports
CreatedTime - DateTime
答案 0 :(得分:3)
直接翻译可能是这样的
array (size=2)
0 =>
array (size=2)
'name' => string 'Name' (length=4)
'value' => string '24' (length=2)
1 =>
array (size=2)
'name' => string 'Name' (length=4)
'value' => string '24' (length=2)
考虑到现在SQL var result = db.WorkItems.Any(wi =>
!wi.IsComplete && wi.TaskId == db.WorkItems
.Where(x => x.WorkItemId == workItemId)
.Select(x => x.TaskId)
.FirstOrDefault()));
,=(subquery)
和IN (subquery)
处理现代数据库的事实相同,您可以尝试这样做
EXISTS(subquery)
答案 1 :(得分:2)
事实证明我只需要从不同的角度解决问题。
我提出了三种具有不同Linq语法的解决方案:
完整的方法链:
var q1 = Warehouse.WorkItems
.Where(workItem => workItem.TaskId == (from wis in Warehouse.WorkItems
where wis.WorkItemId == workItemId
select wis.TaskId).First())
.Any(workItem => !workItem.IsComplete);
混合查询+方法链:
var q2 = Warehouse.WorkItems
.Where(workItem => workItem.TaskId == Warehouse.WorkItems
.Where(wis => wis.WorkItemId == workItemId)
.Select(wis => wis.TaskId)
.First())
.Any(workItem => !workItem.IsComplete);
完整查询:
var q3 = (from wi in Warehouse.WorkItems
where wi.TaskId == (from swi in Warehouse.WorkItems
where swi.WorkItemId == workItemId
select swi.TaskId).First()
where !wi.IsComplete
select 1).Any();
唯一的问题是它提出了一些真正顶起的SQL:
SELECT
(CASE
WHEN EXISTS(
SELECT NULL AS [EMPTY]
FROM [Warehouse].[WorkItems] AS [t0]
WHERE (NOT ([t0].[IsComplete] = 1)) AND ([t0].[TaskId] = ((
SELECT TOP (1) [t1].[TaskId]
FROM [Warehouse].[WorkItems] AS [t1]
WHERE [t1].[WorkItemId] = @p0
)))
) THEN 1
ELSE 0
END) AS [value]
答案 2 :(得分:1)
您可以像这样使用Any()函数:
var result = Warehouse.WorkItems.Any(x => x.WorkItemId != null);
简而言之,您传递了您的条件,在这种情况下,检查您的收藏中的任何项目是否具有ID
变量result
会告诉您集合中的所有项目是否都有ID。
这是一个有用的网页,可以帮助您开始使用LINQ:http://www.dotnetperls.com/linq
答案 3 :(得分:1)
原始SQL中的子查询是无用的,因此不是Any()用法的好例子。它很简单:
SELECT COUNT(*)
FROM Warehouse.WorkItems wi
WHERE WorkItemId = @WorkItemId
AND wi.IsComplete = 0;
看起来,因为结果只有0或1,猜测目的并且基于寻求如何编写Any(),它可以写成:
SELECT CASE WHEN EXISTS ( SELECT *
FROM Warehouse.WorkItems wi
WHERE WorkItemId = @WorkItemId AND
wi.IsComplete = 0 ) THEN 1
ELSE 0
END;
然后使用Any():
是有意义的bool exists = db.WorkItems.Any( wi => wi.WorkItemId == workItemId & !wi.IsComplete );
编辑:我匆忙地误读了原始查询,抱歉。以下是Linq用法的更新:
bool exists = db.WorkItems.Any( wi =>
db.WorkItems
.SingleOrDefault(wi.WorkItemId == workItemId).TaskId == wi.TaskId
&& !wi.IsComplete );
如果原始SQL中需要计数:
var count = db.WorkItems.Count( wi =>
db.WorkItems
.SingleOrDefault(wi.WorkItemId == workItemId).TaskId == wi.TaskId
&& !wi.IsComplete );
再次抱歉让人感到困惑。