Jim Jim - 2 years ago 141
C# Question

IDbSet with IEnumerable Linq where casting required?

I am using IDbSet for a result set and trying to construct the "IN" type clause using LinQ.
My code is as follows:

public IDbSet<User> Users { get; set; }

public IDbSet<User> GetUsers(params int[] IDs)
{
return from u in Users
where IDs.Contains(u.Id)
select u;
}


The complier does not like the where it states:

Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Data.Entity.IDbSet'. An explicit conversion exists (are you missing a cast?)

I have tried the usual casting and As(ing). But I cannot seem to get the compiler to accept this.
Am I in error here?

Answer Source

You should not return query results as IDbSet<T>.

An IDbSet represents the collection of all entities in the context, or that can be queried from the database, of a given type. DbSet is a concrete implementation of IDbSet.

from MSDN

You're trying to get only subset of entities. That's what IQueryable<T>/IEnuemerable<T> are for. Change method declaration to return IQueryable<User>:

public IQueryable<User> GetUsers(params int[] IDs)
{
    return from u in Users
           where IDs.Contains(u.Id)
           select u;
}

Difference between IQueryable<T> and IEnuemerable<T> is that when you return IEnumerable<T> every next LINQ query set on that instance will be executed as LINQ to Object, so you're SQL will not be affected:

var items = GetUsers().Select(x => x.SomeColumnName);

This one would still bring all columns from Users table into memory and project them as LINQ to Objects query.

With method returning IQueryable<T> the same code would affect how generated SQL looks like: data from only one column would be fetched from DB.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download