使EF生成的查询有效

时间:2014-02-10 15:40:11

标签: c# entity-framework entity-framework-5

目前,当Table2中不存在记录时,我需要将Tabel1(SourceTable)中的记录复制到Table2(TargetTable)以及其他一些条件。

我正在使用EntityFramework来完成这项工作。当我使用下面的查询从源表中获取记录时,我注意到实体框架正在使用目标表的左连接,这非常慢,当我替换为不存在时,它的工作速度很快。

所以如何实现在下面的场景中不存在?

随着你可以看到2个内部联接与同一个表?为什么会这样?

一般如何覆盖EF生成的查询?

我们可以通过映射存储过程来完成上述操作,但我希望不使用SP映射。

Below is the Entity diagram

查询我以前用过:

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}

1 个答案:

答案 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改进的领域之一,也许值得一试。