目前,当Table2中不存在记录时,我需要将Tabel1(SourceTable)中的记录复制到Table2(TargetTable)以及其他一些条件。
我正在使用EntityFramework来完成这项工作。当我使用下面的查询从源表中获取记录时,我注意到实体框架正在使用目标表的左连接,这非常慢,当我替换为不存在时,它的工作速度很快。
所以如何实现在下面的场景中不存在?
随着你可以看到2个内部联接与同一个表?为什么会这样?
一般如何覆盖EF生成的查询?
我们可以通过映射存储过程来完成上述操作,但我希望不使用SP映射。
查询我以前用过:
var records = dal.SourceTransactions.Where((o) =>
o.Policy.Quote.Type == "1"
&& (o.TransactionType == 1 || o.TransactionType == 2 || o.TransactionType == 3 || o.TransactionType == 4)
&& o.TransactionDate < System.DateTime.Now &&
o.TargetTransaction == null);
生成EF查询:
{SELECT
[Filter1].[ID1] AS [ID],
[Filter1].[TransactionDate] AS [TransactionDate],
[Filter1].[TransactionType] AS [TransactionType],
[Filter1].[PolicyId] AS [PolicyId]
FROM (SELECT [Extent1].[ID] AS [ID1], [Extent1].[TransactionDate] AS [TransactionDate], [Extent1].[TransactionType] AS [TransactionType], [Extent1].[PolicyId] AS [PolicyId]
FROM [dbo].[SourceTransactions] AS [Extent1]
INNER JOIN [dbo].[Policies] AS [Extent2] ON [Extent1].[PolicyId] = [Extent2].[ID]
INNER JOIN [dbo].[Quotes] AS [Extent3] ON [Extent2].[QuoteId] = [Extent3].[ID]
INNER JOIN [dbo].[Quotes] AS [Extent4] ON [Extent2].[QuoteId] = [Extent4].[ID]
WHERE ([Extent1].[TransactionType] IN (1,2,3,4)) AND
([Extent1].[TransactionDate] < (SysDateTime())) AND (N'1' = [Extent3].[Type]) AND ([Extent4].[Type] IS NOT NULL) )
AS [Filter1]
LEFT OUTER JOIN [dbo].[TargetTransactions] AS [Extent5] ON [Filter1].[ID1] = [Extent5]. [SourceTransactionID]
WHERE [Extent5].[SourceTransactionID] IS NULL}
答案 0 :(得分:2)
您可以强制执行EXISTS
查询:
dal.SourceTransactions
.Where(o => o.Policy.Quote.Type == "1"
&& (o.TransactionType == 1
|| o.TransactionType == 2
|| o.TransactionType == 3
|| o.TransactionType == 4)
&& o.TransactionDate < System.DateTime.Now
&& !dal.TargetTransactions
.Any(t => t.SourceTransactionID == o.ID)
因此,您明确为TargetTransactions
创建子查询。我假设dal
是一个上下文实例,因此它也公开了TargetTransactions
。
当然,你必须将EF按摩到最佳查询中太糟糕了。这可能是EF 6改进的领域之一,也许值得一试。