StackOverflow!
I have a MS SQL database. The part of this database is presented at the next picture

I’m trying to make a complosable query, where I’m trying to find patients who had events with particular evEventKindID. For example, I want to find patients who have an event with (evEventKindtID == 1) and an event with (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());
}
}
The problem is that every next iteration can return more elements than the previous. It counfuses me. How can query from query return more entities than the first query?
In SQL Server Profiler I’ve found the SQL queries, generated by ADO .NET EF. In the place {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]
In the place {2} on the first iteration:
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
And in the place {2} on the second iteration:
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
What do you think about this problem?
This is a common confusion with
foreach. Queries that refer to variables get their parameter values when the query is executed, not when the parameter is bound. So you can haveIn your case, your
foreachloop has one variablelimit. You refer to it multiple times, but those multiple references all see the same value. Which is why you seeBoth parameters have the value 31, the 29 from the first iteration is gone.
The easiest way around this is to create a new variable each time: