【问题标题】:Linq to Entity Framework (v1)Linq 到实体框架 (v1)
【发布时间】:2010-10-03 03:51:03
【问题描述】:

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

所以 - 目前我们有一个返回所有队列的基本 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 工作。

【问题讨论】:

    标签: vb.net linq linq-to-entities


    【解决方案1】:

    您可以通过使用 .Select() 开始优化这一点,以仅检索您关心的列,并可能使用 .Skip().Take() 进行分页

    另外,您为什么不使用 select 语句,而不是获取所有 WorkItems:

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

    如果您只需要一个 WorkItems 的计数,请去掉 .Include("WorkItems")。

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

    【讨论】:

    • 太棒了。语法看起来不错,而且我对 C# 没问题 - 这是我选择的语言,但之前的开发人员选择了 VB.NET,所以我现在坚持使用它。我已经设法进行了快速而肮脏的修复 - 通过归档所有已完成的工作项目(这就是为什么有这么多记录的原因)。我想我可以在那里扩展您的语法,以有条件地选择 status Complete 的计数。这意味着我可以继续将所有记录保存在同一个地方,而不是仅仅因为查询效率低下而移动它们——我从不热衷于位置提供的状态。
    猜你喜欢
    • 2017-07-07
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 2021-12-25
    相关资源
    最近更新 更多