2012-09-02 66 views
4

StackOverflow!ADO中的可組合查詢.NET EF每次迭代返回更多實體

我有一個MS SQL數據庫。該數據庫的一部分呈現在下一圖片

http://i.stack.imgur.com/DFnc5.png

我試圖做一個complosable查詢,在那裏我試圖找到患者誰曾與特別evEventKindID事件。例如,我想查找具有事件(evEventKindtID == 1)和事件(evEventKindID == 1)的患者。

var query = from pt in db.tblPatient 
      select pt; 
var list = query.ToList();// {1} 

foreach (var limit in group.limits.Values) 
{ 
     if (limit.eventKind.Type == TypeOfEventKind.ekEvent) 
     { 
      query = from pt in query 
      where (pt.tblEvent.Count(j => j.evEventKindID == limit.eventKind.ID) > 0) 
           select pt;// {2} 

      list = query.ToList(); 
      MessageBox.Show(query.Count().ToString()); 
     } 
} 

問題是每一個下一個迭代都可以返回比以前更多的元素。它支持我。如何從查詢返回比第一個查詢更多的實體?

在SQL Server Profiler中,我找到了由ADO .NET EF生成的SQL查詢。在該地方{1}:

SELECT 
[Extent1].[ptID] AS [ptID], 
[Extent1].[ptFullName] AS [ptFullName], 
[Extent1].[ptHomeAddress] AS [ptHomeAddress], 
[Extent1].[ptPhone] AS [ptPhone], 
[Extent1].[ptBirthDate] AS [ptBirthDate], 
[Extent1].[ptIsMale] AS [ptIsMale], 
[Extent1].[ptUserID] AS [ptUserID], 
[Extent1].[ptINN] AS [ptINN], 
[Extent1].[ptSNILS] AS [ptSNILS] 
FROM [dbo].[tblPatient] AS [Extent1] 

在該地方{2}在第一次迭代:

exec sp_executesql N'SELECT 
[Project1].[ptID] AS [ptID], 
[Project1].[ptFullName] AS [ptFullName], 
[Project1].[ptHomeAddress] AS [ptHomeAddress], 
[Project1].[ptPhone] AS [ptPhone], 
[Project1].[ptBirthDate] AS [ptBirthDate], 
[Project1].[ptIsMale] AS [ptIsMale], 
[Project1].[ptUserID] AS [ptUserID], 
[Project1].[ptINN] AS [ptINN], 
[Project1].[ptSNILS] AS [ptSNILS] 
FROM (SELECT 
    [Extent1].[ptID] AS [ptID], 
    [Extent1].[ptFullName] AS [ptFullName], 
    [Extent1].[ptHomeAddress] AS [ptHomeAddress], 
    [Extent1].[ptPhone] AS [ptPhone], 
    [Extent1].[ptBirthDate] AS [ptBirthDate], 
    [Extent1].[ptIsMale] AS [ptIsMale], 
    [Extent1].[ptUserID] AS [ptUserID], 
    [Extent1].[ptINN] AS [ptINN], 
    [Extent1].[ptSNILS] AS [ptSNILS], 
    (SELECT 
     COUNT(1) AS [A1] 
     FROM [dbo].[tblEvent] AS [Extent2] 
     WHERE ([Extent1].[ptID] = [Extent2].[evPatientID]) AND ([Extent2].[evEventKindID] = @p__linq__0)) AS [C1] 
    FROM [dbo].[tblPatient] AS [Extent1] 
) AS [Project1] 
WHERE [Project1].[C1] > 0',N'@p__linq__0 int',@p__linq__0=29 

而在地方{2}在第二次迭代:

exec sp_executesql N'SELECT 
[Project2].[ptID] AS [ptID], 
[Project2].[ptFullName] AS [ptFullName], 
[Project2].[ptHomeAddress] AS [ptHomeAddress], 
[Project2].[ptPhone] AS [ptPhone], 
[Project2].[ptBirthDate] AS [ptBirthDate], 
[Project2].[ptIsMale] AS [ptIsMale], 
[Project2].[ptUserID] AS [ptUserID], 
[Project2].[ptINN] AS [ptINN], 
[Project2].[ptSNILS] AS [ptSNILS] 
FROM (SELECT 
    [Project1].[ptID] AS [ptID], 
    [Project1].[ptFullName] AS [ptFullName], 
    [Project1].[ptHomeAddress] AS [ptHomeAddress], 
    [Project1].[ptPhone] AS [ptPhone], 
    [Project1].[ptBirthDate] AS [ptBirthDate], 
    [Project1].[ptIsMale] AS [ptIsMale], 
    [Project1].[ptUserID] AS [ptUserID], 
    [Project1].[ptINN] AS [ptINN], 
    [Project1].[ptSNILS] AS [ptSNILS], 
    (SELECT 
     COUNT(1) AS [A1] 
     FROM [dbo].[tblEvent] AS [Extent3] 
     WHERE ([Project1].[ptID] = [Extent3].[evPatientID]) AND ([Extent3].[evEventKindID] = @p__linq__1)) AS [C1] 
    FROM (SELECT 
     [Extent1].[ptID] AS [ptID], 
     [Extent1].[ptFullName] AS [ptFullName], 
     [Extent1].[ptHomeAddress] AS [ptHomeAddress], 
     [Extent1].[ptPhone] AS [ptPhone], 
     [Extent1].[ptBirthDate] AS [ptBirthDate], 
     [Extent1].[ptIsMale] AS [ptIsMale], 
     [Extent1].[ptUserID] AS [ptUserID], 
     [Extent1].[ptINN] AS [ptINN], 
     [Extent1].[ptSNILS] AS [ptSNILS], 
     (SELECT 
      COUNT(1) AS [A1] 
      FROM [dbo].[tblEvent] AS [Extent2] 
      WHERE ([Extent1].[ptID] = [Extent2].[evPatientID]) AND ([Extent2].[evEventKindID] = @p__linq__0)) AS [C1] 
     FROM [dbo].[tblPatient] AS [Extent1] 
    ) AS [Project1] 
    WHERE [Project1].[C1] > 0 
) AS [Project2] 
WHERE [Project2].[C1] > 0',N'@p__linq__0 int,@p__linq__1 int',@p__linq__0=31,@p__linq__1=31 

您對這個問題有什麼看法?

回答

1

這是一個與foreach常見的混淆。引用變量的查詢在執行查詢時獲取其參數值,而不是在綁定參數時獲取它們的參數值。所以,你可以有

int orderId = 1; 
var query = from o in context.Orders where o.Id == orderId; 
orderId = 2; 
MessageBox.Show(query.Single().Id.ToString()); // shows that order 2 was retrieved 

在你的情況,你的foreach循環有一個變量limit。您多次引用它,但這些多個引用都會看到相同的值。這就是爲什麼你看到

N'@p__linq__0 int,@p__linq__1 int',@p__linq__0=31,@p__linq__1=31 

兩個參數的值都是31​​,從第一次迭代29。

解決這個問題的最簡單方法是每次創建一個新的變量:

foreach (var limit in group.limits.Values) 
{ 
    var locallimit = limit; 
    // refer to locallimit in your query, not to limit 
} 
+0

謝謝!這是答案! – mpMelnikov