views:

83

answers:

2

I have the following LINQ query. The problem is it's returning 13k results when tblSurveys only has 20 total. What am I doing wrong?

from s in surveyContext.tblSurveys
from st in surveyContext.tblTypes_for_Surveys
from t in surveyContext.tblSurvey_Types
where (s.Survey_Date >= startDate && s.Survey_Date <= stopDate) && 
      (s.Unsubstantiated || 
         (st.SurveyID == s.SurveyID && st.SurveyTypeID == t.SurveyTypeID && 
         t.UnsubstantiatedAvailable && (from d in surveyContext.tblDeficiencies
                                         where d.SurveyID == s.SurveyID
                                        select d.DeficiencyID).Count() == 0))
orderby s.Survey_Date
select s;
+5  A: 

I can see a cross join in there, look at the <-------

           from s in surveyContext.tblSurveys
           from st in surveyContext.tblTypes_for_Surveys
           from t in surveyContext.tblSurvey_Types
           where (s.Survey_Date >= startDate && s.Survey_Date <= stopDate) && 
                 (s.Unsubstantiated || <-------
                    (st.SurveyID == s.SurveyID && st.SurveyTypeID == t.SurveyTypeID && 
                    t.UnsubstantiatedAvailable && (from d in surveyContext.tblDeficiencies
                                                   where d.SurveyID == s.SurveyID
                                                   select d.DeficiencyID).Count() == 0))
           orderby s.Survey_Date
           select s;

it seem you need to do a left join in here

Fredou
why a downvote?
Fredou
I don't see what's bad about a cross join. (Just had to look it up) (I didn't down vote it) Either return a tblSurvey record if (the date stuff and s.Unsubstianted) or (date stuff and everything else)
jamone
cross join is, if you have 20 record in tblSurveys and 30 in tblTypes_for_Surveys then 50 in tblSurvey_Types, this will return 30,000 rows
Fredou
A cross join will produce the Cartesian product of your three sets (hence your 13k rows instead of 20). You should either use explicit join statements or set the join conditions in your where clause.
Winston Smith
+1  A: 

Do you have foreign keys and relationships setup in your database? If so, you can greatly simplify your query. I'd also recommend renaming your tables in the .dbml file so they aren't all prefixed with 'tbl'.

If you do have relationships setup, your query could look (something) like this:

from s in surveyContext.tblSurveys
where (s.Survey_Date >= startDate && s.Survey_Date <= stopDate) && 
     (s.Unsubstantiated || 
        (s.tblTypes_for_Surveys.Any(st => st.tblSurvey_Type.UnsubstantiatedAvailable) && s.tblDeficiencies.Count() == 0))
orderby s.Survey_Date
select s;
Ryan Versaw
Wow and I thought LINQ-SQL was powerful before. This is great. That just made a lot of my stuff way easier knowing that the foreign keys/relationships handles this for you.
jamone