簡體   English   中英

LINQ-基於Where子句創建子查詢

[英]LINQ - Creating Subquery based on Where clause

我看到了我不了解的LINQ行為,我真的想防止它發生,因為這使我的查詢運行得比預期慢得多。

下面的C#代碼產生了我期望的結果,但是當我向它添加一個額外的動態過濾器時,事情開始往南走。

resultChildrenTC = resultChildrenTC.Where(x => x.parentId != 0 && x.clientId == this.clientId);
var me = resultChildrenTC.ToList();

以上C#的良好結果以及我的期望。

...
CASE WHEN (1 = [Extent12].[accept_revisions_ind]) THEN 1 ELSE 0 END AS [C14], 
[Extent4].[client_id] AS [client_id]
FROM            [dbo].[automation_sequence_executions] AS [Extent1]
INNER JOIN [dbo].[automation_sequence_status] AS [Extent2] ON [Extent1].[automation_sequence_status_id] = [Extent2].[id]
INNER JOIN [dbo].[automation_sequences] AS [Extent3] ON [Extent1].[automation_sequence_id] = [Extent3].[id]
INNER JOIN [dbo].[project] AS [Extent4] ON [Extent3].[project_id] = [Extent4].[id]
LEFT OUTER JOIN [dbo].[automation_sequence_execution_results] AS [Extent5] ON [Extent1].[id] = [Extent5].[auto_seq_exec_id]
LEFT OUTER JOIN [dbo].[automation_sequence_test_case_status] AS [Extent6] ON [Extent1].[runtime_case_grp_status] = [Extent6].[id]
LEFT OUTER JOIN [dbo].[users] AS [Extent7] ON [Extent1].[executed_by_id] = [Extent7].[id]
INNER JOIN [dbo].[users] AS [Extent8] ON [Extent3].[created_by_id] = [Extent8].[id]
LEFT OUTER JOIN [dbo].[users] AS [Extent9] ON [Extent3].[last_modified_by_id] = [Extent9].[id]
LEFT OUTER JOIN [dbo].[machines] AS [Extent10] ON [Extent1].[machine_id] = [Extent10].[id]
LEFT OUTER JOIN [dbo].[execution_sync_queue] AS [Extent11] ON ([Extent1].[id] = [Extent11].[execution_id]) AND (0 = [Extent11].[status])
LEFT OUTER JOIN [dbo].[execution_schedule] AS [Extent12] ON [Extent1].[schedule_id] = [Extent12].[id]
WHERE (0 <> (CASE WHEN ([Extent1].[parent_group_exec_id] IS NULL) THEN 0 ELSE [Extent1].[parent_group_exec_id] END)) AND (1 = [Extent4].[status]) AND ([Extent4].[client_id] = @p__linq__0)',N'@p__linq__0 int',@p__linq__0=0

現在,一旦我從上面編輯C#代碼以接受其他過濾器,事情就會發生變化...

resultChildrenTC = resultChildrenTC.Where(x => x.parentId != 0 && x.clientId == this.clientId).Where(filterExpression);
var me = resultChildrenTC.ToList();

在運行時,LINQ決定創建一個子查詢。 這很重要,因為稍后我需要在此查詢上運行EXISTS,並希望在此過濾器上進行更多擴展,但是由於它總是創建此隨機子查詢,因此會破壞我的過濾,從而導致性能下降。 是什么給了並且有辦法將其關閉?

[Filter1].[client_id1] AS [client_id]
FROM          (SELECT [Extent1].[id] AS [id1], [Extent1].[machine_id] AS [machine_id], [Extent1].[executed_by_id] AS [executed_by_id], [Extent1].[external_test_mgmt_id] AS [external_test_mgmt_id1], [Extent1].[schedule_id] AS [schedule_id], [Extent1].[parent_group_exec_id] AS [parent_group_exec_id], [Extent1].[patriarch_id] AS [patriarch_id], [Extent1].[runtime_case_grp_status] AS [runtime_case_grp_status], [Extent1].[execution_start_time] AS [execution_start_time], [Extent2].[id] AS [id3], [Extent2].[name] AS [name2], [Extent2].[fail_alert_ind] AS [fail_alert_ind], [Extent2].[hold_alert_ind] AS [hold_alert_ind], [Extent2].[complete_ind] AS [complete_ind], [Extent3].[id] AS [id2], [Extent3].[name] AS [name1], [Extent3].[created_by_id] AS [created_by_id], [Extent3].[last_modified_by_id] AS [last_modified_by_id], [Extent3].[case_group_ind] AS [case_group_ind], [Extent4].[name] AS [name3], [Extent4].[client_id] AS [client_id1]
FROM          (SELECT [Extent1].[id] AS [id1], [Extent1].[machine_id] AS [machine_id], [Extent1].[executed_by_id] AS [executed_by_id], [Extent1].[external_test_mgmt_id] AS [external_test_mgmt_id1], [Extent1].[schedule_id] AS [schedule_id], [Extent1].[parent_group_exec_id] AS [parent_group_exec_id], [Extent1].[patriarch_id] AS [patriarch_id], [Extent1].[runtime_case_grp_status] AS [runtime_case_grp_status], [Extent1].[execution_start_time] AS [execution_start_time], [Extent2].[id] AS [id3], [Extent2].[name] AS [name2], [Extent2].[fail_alert_ind] AS [fail_alert_ind], [Extent2].[hold_alert_ind] AS [hold_alert_ind], [Extent2].[complete_ind] AS [complete_ind], [Extent3].[id] AS [id2], [Extent3].[name] AS [name1], [Extent3].[created_by_id] AS [created_by_id], [Extent3].[last_modified_by_id] AS [last_modified_by_id], [Extent3].[case_group_ind] AS [case_group_ind], [Extent4].[name] AS [name3], [Extent4].[client_id] AS [client_id1]
    FROM    [dbo].[automation_sequence_executions] AS [Extent1]
    INNER JOIN [dbo].[automation_sequence_status] AS [Extent2] ON [Extent1].[automation_sequence_status_id] = [Extent2].[id]
    INNER JOIN [dbo].[automation_sequences] AS [Extent3] ON [Extent1].[automation_sequence_id] = [Extent3].[id]
    INNER JOIN [dbo].[project] AS [Extent4] ON [Extent3].[project_id] = [Extent4].[id]
    WHERE (0 <> (CASE WHEN ([Extent1].[parent_group_exec_id] IS NULL) THEN 0 ELSE [Extent1].[parent_group_exec_id] END)) AND ([Extent3].[name] LIKE ''%UAT%'') AND (1 = [Extent4].[status]) ) AS [Filter1]
LEFT OUTER JOIN [dbo].[automation_sequence_execution_results] AS [Extent5] ON [Filter1].[id1] = [Extent5].[auto_seq_exec_id]
LEFT OUTER JOIN [dbo].[automation_sequence_test_case_status] AS [Extent6] ON [Filter1].[runtime_case_grp_status] = [Extent6].[id]
INNER JOIN [dbo].[users] AS [Extent7] ON [Filter1].[executed_by_id] = [Extent7].[id]
INNER JOIN [dbo].[users] AS [Extent8] ON [Filter1].[created_by_id] = [Extent8].[id]
INNER JOIN [dbo].[users] AS [Extent9] ON [Filter1].[last_modified_by_id] = [Extent9].[id]
LEFT OUTER JOIN [dbo].[machines] AS [Extent10] ON [Filter1].[machine_id] = [Extent10].[id]
LEFT OUTER JOIN [dbo].[execution_sync_queue] AS [Extent11] ON (0 = [Extent11].[status]) AND ([Filter1].[id1] = [Extent11].[execution_id])
LEFT OUTER JOIN [dbo].[execution_schedule] AS [Extent12] ON [Filter1].[schedule_id] = [Extent12].[id]
WHERE [Filter1].[client_id1] = @p__linq__0',N'@p__linq__0 int',@p__linq__0=0

更新-Where子句的影響

每當我在字符串字段上執行LIKE時,就會發生這種情況。 似乎Contains正在創建這種奇怪的行為。

子查詢:

resultChildrenTC = resultChildrenTC.Where(x => x.parentId != 0 && x.clientId == this.clientId).Where(x=>x.Name.Contains("wes"));

沒有子查詢:

resultChildrenTC = resultChildrenTC.Where(x => x.parentId != 0 && x.clientId == this.clientId).Where(x=>x.Name == "wes");

更新-可能的推理

我創建了許多可能都相關的票證,這些票證當時我還不知道。

從我對LINQ到實體的了解中,在查詢中使用包含的FK是一個錯誤。 可以在以下帖子中找到對此的更詳細的視圖:

LINQ-基於JOIN順序的SQL腳本更改

如果您已經知道要多次運行相同的查詢,則可以以某種方式緩存它以減少服務器的工作量。

var mycatch = resultChildrenTC.Where(x => x.parentId != 0 && x.clientId == this.clientId).ToList();
var result1 = mycache .Where(filterExpression1)
var result2 = mycache .Where(filterExpression2)
var result3 = mycache .Where(filterExpression2)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM