Linq to Entities over EF 4 on SQL Server 2005
'Cannot compare elements of type 'System.Collections.Generic.ICollection`1'. Only primitive types (such as Int32, String, and Guid) and entity types are supported.'
Entities & Relationships (Navigation Properties):
Case (1 <-> ∞) MeetingCase (1 <-> ∞) MeetingCaseOutcomes
The offending code is:
IQueryable<Case> cases; // this is obviously attached to a context and able to access data)
var broken = cases
.Where(c => c.MeetingCases
.Where(mc => mc.ExpectedStartDateTime <= DateTime.Now)
.Any(m => m.MeetingCaseOutcomes == null || m.MeetingCaseOutcomes.Count == 0));
I assume the problem is due to lack of support for the 'Any' operator, though I had thought this would work in EF 4 (since support for the related 'Contains' operator has been added).
How should I re-structure this call to produce what I want?
I have been working with EF for several months now and understand many of the runtime gotchas
UPDATE:
The Where clause above does contain a predicate, as follows:
c.MeetingCases.Where(mc => mc.ExpectedStartDateTime <= DateTime.Now)
.Any(m => m.MeetingCaseOutcomes == null || m.MeetingCaseOutcomes.Count == 0)
Because Any
returns a boolean, the whole thing produces a predicate expression.
Also, the intent of this logic is to return a set of Case objects which do not have MeetingCaseOutcome records for any MeetingCase record开发者_StackOverflow社区s where the meeting has already taken place (hence the comparison to DateTime.Now). This is part of a meeting scheduling system, and this is to check that Outcomes from each meeting are entered into the system following the meeting taking place.
EF 1 and EF 4 both support .Any()
. The problem is that you're not using it enough. :)
IQueryable<Case> cases; // this is obviously attached to a context and able to access data)
var broken = cases
.Where(c => c.MeetingCases
.Where(mc => mc.ExpectedStartDateTime <= DateTime.Now)
.Any(m => !m.MeetingCaseOutcomes.Any()));
This part is the problem:
Where(c => c.MeetingCases
.Where..
.Where
requires a Expression<Func<T,bool>>
, in otherwords a predicate which returns true/false. But your supplying it a predicate which returns a sequence of elements.
I think that second .Where
needs to be changed to .Any
or .All
.
I'm struggling to decipher what query your attempting to execute, but i'm assuming you want a list of Case
where at least one associated MeetingCase
has a ExpectedStartDateTime
before today.
So your query should be:
var cases = cases
.Where(case => case.MeetingCases
.Any(caseMeeting => caseMeeting.ExpectedStartDateTime <= DateTime.Now));
I'm not sure what your trying to do with that last .Any
clause.
Also - don't forget about eager-loading/projection problems. You say "it's attached to the context", which is fine - but c.MeetingCases
will not return anything unless you have lazy loading on or are eager loading beforehand.
精彩评论