2013-05-29 45 views
1

我一直認爲存在查詢的LINQ to SQL等價物是使用Any()。但我最近在LINQ中編寫了一個查詢,它基本上試圖查找單個表中是否存在重複記錄。LINQ中的任何vs Where子句

任何context.Contacts.Any(c => ((c.FirstName == contact.FirstName && c.LastName == contact.LastName && c.AddressLine1 == contact.AddressLine1 && c.Zip == contact.Zip)|| (!String.IsNullOrEmpty(contact.Email) && c.Email == contact.Email)))

匹配的標準很簡單,找到相同的名字,姓氏和AddressLine1或同電子郵件聯繫。此查詢在30秒內超時(默認),此表中只有500K行。

context.Contacts.Where(c => ((c.FirstName == contact.FirstName && c.LastName == contact.LastName && c.AddressLine1 == contact.AddressLine1 && c.Zip == contact.Zip)|| (!String.IsNullOrEmpty(contact.Email) && c.Email == contact.Email))).Count()>0

我被迫使用Where子句,然後做計數大於0找到,如果在設定存在任何重複。我無法理解的是,爲什麼LINQ to SQL在簡單的Any子句中超時。 這裏的任何解釋都會非常棒。

編輯

SQL從從LINQ墊 任何

SELECT 
(CASE 
    WHEN EXISTS(
     SELECT NULL AS [EMPTY] 
     FROM [Accounts].[Contacts] AS [t0] 
     WHERE ([t0].[CompanyID] = @p0) AND ((([t0].[FirstName] = @p1) AND ([t0].[LastName] = @p2) AND ([t0].[AddressLine1] = @p3) AND ([t0].[Zip] = @p4)) OR (([t0].[FirstName] = @p5) AND ([t0].[LastName] = @p6) AND (EXISTS(
      SELECT NULL AS [EMPTY] 
      FROM [Accounts].[PhoneNumbers] AS [t1] 
      WHERE ([t1].[ContactNumber] = @p7) AND ([t1].[ContactID] = [t0].[ContactID]) 
      )))) 
     ) THEN 1 
    ELSE 0 
END) AS [value] 

SELECT [t0].[ContactID] 
    ,[t0].[CompanyID] 
    ,[t0].[CompanyTitle] 
    ,[t0].[FirstName] 
    ,[t0].[LastName] 
    ,[t0].[AddressLine1] 
    ,[t0].[AddressLine2] 
    ,[t0].[City] 
    ,[t0].[State] 
    ,[t0].[Zip] 
    ,[t0].[Email] 
    ,[t0].[Salutation] 
    ,[t0].[IsActive] 
FROM [Accounts].[Contacts] AS [t0] 
WHERE ([t0].[CompanyID] = @p0) 
    AND (
     (
      ([t0].[FirstName] = @p1) 
      AND ([t0].[LastName] = @p2) 
      AND ([t0].[AddressLine1] = @p3) 
      AND ([t0].[Zip] = @p4) 
      ) 
     OR (
      ([t0].[FirstName] = @p5) 
      AND ([t0].[LastName] = @p6) 
      AND (
       EXISTS (
        SELECT NULL AS [EMPTY] 
        FROM [Accounts].[PhoneNumbers] AS [t1] 
        WHERE ([t1].[ContactNumber] = @p7) 
         AND ([t1].[ContactID] = [t0].[ContactID]) 
        ) 
       ) 
      ) 
     ) 
+1

可能是'Any()'方法中linq到sql的解析器沒有生成一個好的查詢。你有配置文件來檢查它嗎? –

+0

這是什麼想法,但我沒有生成的SQL。我使用LINQ鍵盤和生成的SQL幾乎是相同的除了計數部分 – Apurav

+0

我討厭這麼說,但這真的是一個不錯的LINQ性能工具派上用場。您可能想看看http://stackoverflow.com/questions/1389930/tools-and-techniques-to-optimize-a-linq-to-sql-query我已經使用Hibernating Rhino的性能工具取得了巨大的成功。查看你的LINQ查詢生成的內容非常有趣。它幫助我瞭解了不要做什麼;-) –

回答

0

不能完全肯定,如果這是你想要的,但你可以比較,我猜您不會經常運行測試,因爲在將數據輸入到數據庫之前,最好測試是否存在。

如果你想找到重複然後

var queryA = from a in db.someTable 
      select a.value; 
foreach(var row in queryA){ 
Console.Write(queryA.Where(b => b == row).Count() > 1 ? row: ""); 
} 

如果你只是想,如果那麼它存在的測試。

var queryA = from a in db.someTable 
      select a.value; 
var queryB = queryA; 
queryB.Distinct(); 
Console.Write(queryB.Count() != queryA.Count() ? "Yes" : "No"); 
+0

這將工作,但我必須這樣做多次運行。相同的邏輯用於搜索記錄,也用於插入前。我認爲foreach實際上會增加算法時間。所以不會有用。 – Apurav

+0

如果您在插入之前檢查重要的列,則不必在之後執行。 無論如何,你想在表上做一個雙循環,因爲你必須自己檢查數據對它自己。 –