2016-08-10 3 views
1

Ich habe eine Klasse Basis von einer anderen Klasse geerbt:Basistyp Abfrage in Entity Framework

class Base { } 
class Derived : Base { } 

Entity Framework speichert nur Instanzen der abgeleiteten Klasse. Ich möchte nur Spalten auswählen, die den Feldern in der Basisklasse entsprechen, und sie als IEnumerable<Base> zurückgeben. Gibt es einen einfachen Weg, dies zu tun?

+1

Warum nicht einfach Abfrage Abgeleitete und werfen dann die Ergebnisse auf Basis? – stuartd

+0

@stuartd: Vielen Dank für eine schnelle Antwort. Cast <> war sicher das erste, was ich ausprobiert habe. Als Ergebnis habe ich diesen Fehler erhalten: "Der Typ 'Derived' konnte nicht in den Typ 'Base' umgewandelt werden. LINQ to Entities unterstützt nur das Generieren von EDM-Primitiven oder Aufzählungstypen." Es ist nur natürlich, da 'Base' niemals in EF gespeichert wird, nur 'Derived' wird gespeichert. –

+1

Nein, es gibt keine einfache Möglichkeit, nur Basisspalten auszuwählen. Aber du kannst @stuartd Ratschläge nehmen. Es wird kein 'Cast' benötigt, nur' .AsEnumerable () 'am Ende der Abfrage. –

Antwort

2

Eigentlich sobald Base Typ nicht als Einheit von EF erkannt wird (weil es aus irgendeinem Grund nicht zu Entität vorstehenden Typen erlaubt), können Sie die folgenden einfachen Helfer aus meiner Antwort auf c# How can I create a collection of custom objects without going through each field verwenden:

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)))); 
    } 
} 

wie folgt aus:

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