IQueryable Lambda-Projektion Syntax
Habe ich ein IQueryable, deren Entity Framework 4 Objekte möchte ich zu Projekt, um Ihre DTO-äquivalente. Ein solches Objekt 'Person' ist ein EF4-Klasse, und die entsprechenden POCO PersonP ist eine Klasse, die ich definiert haben. Ich bin mit Automapper zu Karte zwischen Ihnen. Jedoch, wenn ich versuche, den folgenden code:
IQueryable<Person> originalModel = _repo.QueryAll();
IQueryable<PersonP> projection = originalModel.Select(e => Mapper.Map<Person, PersonP>(e));
Die Projektion erzeugt diesen Fehler zur Laufzeit:
LINQ to Entities does not recognize the method 'TestSite.Models.PersonP Map[Person,PersonP](TestSite.DataLayer.Model.Person)' method, and this method cannot be translated into a store expression.
Was ist die richtige syntax zum erstellen einer IQueryable<PersonP>
Projektion mit Automapper? Danke.
P. S. Automapper ist richtig konfiguriert - ich benutze es in anderen Orten hin und her konvertieren zwischen Person und PersonP, d.h. Mapper.Map<Person, PersonP>(myPersonObject)
richtig gibt eine PersonP
Objekt.
BEARBEITEN (mehr code):
Ich bin mit diesem für eine helper-Funktion zu binden EF4 Person POCOs (PersonP) zu einem Telerik Grid - das wird nicht serialisiert die Entitäten selbst richtig, da Sie zirkulären Bezüge enthalten (z.B. navigation Eigenschaften). Mein code sieht wie folgt aus:
public static GridModel GetGridModel<TEntity, TPoco>(IRepository<TEntity> repo, GridState gridState) where TEntity : EntityObject
{
var originalModel = repo.QueryAll().ToGridModel(gridState);
var projection = originalModel.Select(e => Mapper.Map<TEntity, TPoco>(e));
return projection.ToGridModel(gridState); //applies filters, sorts, pages, etc...
}
den .ToGridModel
Methode ist eine Erweiterung der Methode auf IQueryable
und es gibt ein Komplexes Objekt, das ich nicht zuverlässig analysieren - so führt dies mich zu glauben, habe ich, um eine Filterung durchzuführen, nachdem ich getan habe, um die Projektion zu POCOs.
UPDATE 2:
Versuchen, die Dinge zu vereinfachen, habe ich eine nicht-generische Methode, wie diese:
public static GridModel GetGridModel2(IRepository<Client> repo, GridState gridState)
{
IQueryable<Client> originalModel = repo.QueryAll();
IQueryable<ClientP> projection = originalModel.Select(c => ClientToClientP(c));
return projection.ToGridModel(gridState);
}
private static ClientP ClientToClientP(Client c)
{
return new ClientP { Id = c.Id, FirstName = c.FirstName };
}
Dieser code auch nicht bei der Erstellung der Projektion. Ich merke, dass IQueryable.Select() hat mehrere überladungen: Ausdruck> als einer von Ihnen. Konnte ich vertrete diese Funktion/Stellvertretung Anruf mit einer dieser überbelastungen?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es nicht. Automapper nicht tun. Es ist das falsche Werkzeug für diese Aufgabe.
Könnte man erstellen Sie einen Automapper-wie Werkzeug, um eine ähnliche Sache für die Abfrage Projektionen. Ich hab mir überlegt es in die Vergangenheit, sondern immer der Schluss gezogen, dass der code mithilfe wäre es weniger lesbar als die Projektion. Ich will nicht zu optimieren, code schreiben Zeit über code-lese-Zeit.
Ihre aktualisierte code funktioniert nicht, weil es nicht ein Ausdruck. Wenn Sie das tun:
...und dann:
...dann wird es funktionieren.
Expression<Function<…
und daher wird transliterate dienew
in einer SQL - kompatiblen Ausdruck. Aber dieMapper.Map
nennen wäre eineInvoke
im Ausdruck Körper, und das wird nicht konvertieren, um SQL.Diese tatsächlich wurde nun behoben, durch den Autor, der AutoMapper hier: http://lostechies.com/jimmybogard/2011/02/09/autoprojecting-linq-queries/
Er stellt eine Implementierung, die es braucht, gewünschte Projektion und die Abfrage und Abfragen der Datenbank nur für die Felder erforderlich, für das projection mapping.
Siehe auch die follow-on-Artikel von Paul Hiles für einige caching-Verbesserungen.
Hoffe, das hilft.
Wenn Sie hinzufügen .ToList() vor dem Wählen können Sie erzwingen, dass die Zuordnung zu passieren client-Seite (Linq to Objects) anstelle der server-Seite (SQL). Nur stellen Sie sicher, dass Sie getan haben Ihre Filterung ersten, so dass Sie nicht, um die gesamte Tabelle über.
ToGridModel
Methode. Das muss wirklich splitting auseinander, so dass Sie kann filtern und Sortieren, dann rechnen, dann tun Sie, was es sonst noch so braucht, zu tun. Kann die Filter von ihm getrennt, dann überqueren Sie die Grenze, dann Projekt und zusammenstellen der GridModel?