开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜