Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ to Entities Contains Query

I'm trying to use Contains() in a simple query but it is failing, with the error :

Unable to create a constant value of type 'NewsletterApp.Models.NewsletterUser'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.

Edit The intellisense actually directs me to use the NewsletterUser in Contains() -'(NewsletterUser item)'

I read that there were issues searching for an object using Contains() using EF with .NET 3.5, but I am using EF4.2 (also tried 4.1) with .NET 4.0 . Code is below:

        var db = new MyContext(); 

        var newsletterUser = db.NewsletterUsers.Find(UserID);
        var subscriberList = db.Subscribers
              .Where(x => x.NewsletterList.ListOwner.NewsletterUsers.Contains(newsletterUser))
              .ToList();
like image 533
Judo Avatar asked Feb 22 '23 18:02

Judo


1 Answers

I suspect you want this

var db = new MyContext(); 
var newsletterUser = db.NewsletterUsers.Find(UserID);
var subscriberList = db.Subscribers
          .Where(x => x.NewsletterList.ListOwner.NewsletterUsers
                     .Any(y => y.UserId == newsletterUser.UserId))
          .ToList();

Any() checks for the existence of a item that fulfils the criteria specified in the lambda: "y => y.UserId == newsletterUser.UserId".

The exception you were getting: "Only primitive types ('such as Int32, String, and Guid') are supported in this context" is due to limitations set by LINQ to Entities. LINQ to Entities needs to resolve your query in a way that it can express to the database, and it can't do that with the Contains() method with anything other than a primitive type.

The thing is, the code you posted does run fine if you run it against an in memory collection (LINQ to Objects) - that's why it isn't flagged by the compiler.

like image 98
perfectionist Avatar answered Mar 08 '23 08:03

perfectionist