2010-10-01 222 views
1

我目前正在研究解决方案,其中有用户,工作队列和工作项的概念。在基本级别上,用户有一系列分配给他们的工作队列,工作队列包含要完成的工作。Linq to Entity Framework(v1)

所以 - 目前我们有一个基本的Linq查询返回所有的队列,但我希望限制该查询以提高性能 - 基于当前查询,它将最多返回94,000条记录,最多127条工作队列。原因是在这个linq查询中我们包含了WorkItems,这样我们可以(稍后)统计队列中的工作项的数量。我已经扩展了WorkQueue对象来包含一个LinqQuery来计算记录的数量 - 我希望能够工作,但是除非最初的查询包含工作项目,否则失败。

这基本上是使用主/细节类型接口的数据绑定,我有点担心(根据从LINQ生成的跟踪字符串)有大量数据会产生影响性能的数据。

从历史上看,我会使用直接的SQL绑定 - 但以前的开发人员已决定使用EF来做这件事..我也因为我们仍在使用实体框架建模系统的版本1而受到阻碍。

我已经考虑用一个存储过程调用替换查询 - 但这似乎并不能很好地工作 - 给我一个额外的NULL记录。我已经尝试过使用LinqPad - 以及那种作品,但只要你想包括东西,语法就会出现。

这里是我迄今为止...

这里的LINQ查询:

QueueTable.DataSource = From queue In objImageViewerContext.WorkQueues().Include("WorkItems") _ 
             .Where(Function(i) i.Scan_Type = Constants.Work_Queue_Type_Front_End) _ 
             Order By (queue.WorkItems.Count > 0) Descending, queue.Name Ascending 

这里是一个的生成的SQL ...

SELECT  WorkQueue_ID, Name, Work_Type, Functional_Area, Process, Text_Code, Barcode, Scan_Type, SLA_Minutes, Medical_Indicator, IsTeamQueue, 
         C2 AS C1, Role_ID, C4 AS C2, C3, WorkItem_ID, Participant, Last_Action, Last_Modified, Date_Added, Modified_By, Is_Urgent_Action, Image_ID, 
         Queue_ID 
FROM   (SELECT  CASE WHEN ([Project2].[C1] > 0) THEN CAST(1 AS bit) WHEN (NOT ([Project2].[C2] > 0)) THEN CAST(0 AS bit) END AS C1, 
               Project2.WorkQueue_ID, Project2.Name, Project2.Work_Type, Project2.Functional_Area, Project2.Process, Project2.Text_Code, 
               Project2.Barcode, Project2.Scan_Type, Project2.SLA_Minutes, Project2.Medical_Indicator, Project2.IsTeamQueue, Project2.Role_ID, 
               1 AS C2, Extent4.WorkItem_ID, Extent4.Image_ID, Extent4.Queue_ID, Extent4.Participant, Extent4.Last_Action, Extent4.Last_Modified, 
               Extent4.Date_Added, Extent4.Modified_By, Extent4.Is_Urgent_Action, CASE WHEN ([Extent4].[WorkItem_ID] IS NULL) THEN CAST(NULL 
               AS int) ELSE 1 END AS C3, CASE WHEN ([Extent4].[WorkItem_ID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS C4 
         FROM   (SELECT  WorkQueue_ID, Name, Work_Type, Functional_Area, Process, Text_Code, Barcode, Scan_Type, SLA_Minutes, 
                     Medical_Indicator, IsTeamQueue, Role_ID, C1, 
                      (SELECT  COUNT(CAST(1 AS bit)) AS A1 
                      FROM   WorkItems AS Extent3 
                      WHERE  (Project1.WorkQueue_ID = Queue_ID)) AS C2 
               FROM   (SELECT  WorkQueue_ID, Name, Work_Type, Functional_Area, Process, Text_Code, Barcode, Scan_Type, SLA_Minutes, 
                           Medical_Indicator, IsTeamQueue, Role_ID, 
                            (SELECT  COUNT(CAST(1 AS bit)) AS A1 
                            FROM   WorkItems AS Extent2 
                            WHERE  (Extent1.WorkQueue_ID = Queue_ID)) AS C1 
                     FROM   WorkQueues AS Extent1 
                     WHERE  (N'Front End' = Scan_Type)) AS Project1) AS Project2 LEFT OUTER JOIN 
               WorkItems AS Extent4 ON Project2.WorkQueue_ID = Extent4.Queue_ID) AS Project3 

它是如此令人沮丧,因为我知道我可以编写SQL来完成我想要的功能,但我似乎无法让Linq工作。

回答

0

您可以开始使用。选择(),以仅获取您所关心的栏目,并可能使用分页与.Skip(),以优化此乘坐()

此外,而不是抢占了所有的工作项你为什么不使用select语句如:

.Select(i => new { Count = i.WorkItems.Count() }) 

,摆脱.INCLUDE的(“工作项目”),如果你需要的是工作项的计数。

对不起我使用C#,我从来没有在VB写的,但相信你明白我想说

+0

这是brilliant.Syntax似乎确定和我很好用C# - 这是我所选择的语言,但之前的开发人员选择了VB.NET,所以我暂时坚持这一点。我已经设法通过归档所有已完成的工作项目(这就是为什么有这么多记录)来解决一个快速而肮脏的问题。我想我可以扩展你的语法来有条件地选择状态<>完成的计数。这意味着我可以继续将所有记录保留在同一个地方,而不是纯粹因为查询效率低下而移动它们 - 我从不热衷于按位置提供的状态。 – 2010-10-04 11:35:47