Boris Zinchenko
Boris Zinchenko

Reputation: 2282

Base type query in Entity Framework

I have a base class inherited by another class:

class Base { }
class Derived : Base { }

Entity Framework stores only instances of derived class. I want to select only columns, corresponding to the fields in base class and return them as IEnumerable<Base>. Is there an easy way to do this?

Upvotes: 1

Views: 797

Answers (1)

Ivan Stoev
Ivan Stoev

Reputation: 205759

Actually, as soon as Base type is not recognized as entity by EF (because for some reason it does not allow projecting to entity types), you can use the following simple helper from my answer to c# How can I create a collection of custom objects without going through each field:

public static class QueryableExtensions
{
    public static IQueryable<TResult> SelectTo<TResult>(this IQueryable source)
    {
        var sourceType = source.ElementType;
        var resultType = typeof(TResult);
        var parameter = Expression.Parameter(sourceType, "x");
        var bindings =
            from rm in resultType.GetProperties().Concat<MemberInfo>(resultType.GetFields())
            join sm in sourceType.GetProperties().Concat<MemberInfo>(sourceType.GetFields())
                on rm.Name equals sm.Name
            select Expression.Bind(rm, Expression.MakeMemberAccess(parameter, sm));
        var body = Expression.MemberInit(Expression.New(resultType), bindings);
        return source.Provider.CreateQuery<TResult>(Expression.Call(
            typeof(Queryable), "Select", new[] { sourceType, resultType },
            source.Expression, Expression.Quote(Expression.Lambda(body, parameter))));
    }
}

like this:

IQueryable<Derived> yourQuery = ...;
return yourQuery.SelectTo<Base>();

Upvotes: 2

Related Questions