Cast () - Ausnahme: LINQ to Entities unterstützt nur casting EDM primitive oder enumerationstypen
Möchte ich etwas zeigen Entität namens CriminalEvent
in eine Allgemeine MVC-Ansicht, die ich schrieb. Die Sicht erfordert, dass das Modell übergeben ihm obliegt die Ausführung der IDataModel
- Schnittstelle. Jetzt CriminalEvent
hat die Eigenschaften, um diese Schnittstelle zu implementieren, aber unter einem anderen Namen und ich kann es nicht ändern.
Also in meinem code, den ich geerbt CriminalEvent
und meine abgeleitete Klasse (auch als CriminalEvent, dumm, aber ich Schätze, erlaubt es mir, zu vermeiden, viele code-änderungen...) hat explizite interface-code:
Using ViewApp;
public interface IDataModel
{
int ID { get; set; }
int CriminalEventID { get; set; }
}
public class ViewCriminalEvent : AIM.Police.DB.CriminalEvent, IDataModel
{
int IDataModel.ID
{
get { return CriminalEventID; }
set { CriminalEventID = value; }
}
}
(Ich weiß, in diesem Fall die Schnittstelle die ID-Eigenschaft ist gleich CriminalEventID, es ist Ok)
Erwartet, dass ich in der Lage sein zu Lesen der AIM.Police.DB.CriminalEvent
Personen und Auffüllen meiner Ansicht Modell von Linq to Entities-Cast()ing Sie an die abgeleitete CriminalEvent
wie diese:
View-Modell (brauche ich zum Auffüllen der CriminalEvents
Eigenschaft):
Using ViewApp;
public class CriminalEventMainViewModel
{
public IEnumerable<IDataModel> CriminalEvents { get; set; }
public IDataModel SelectedEntity { get; set; }
public string SubEntityDisplayName { get; set; }
public IEnumerable<IDataModel> SubEntityCollection { get; set; }
public IDataModel SelectedSubEntity { get; set; }
}
und der Controller-code:
Using ViewApp;
private ViewResult CriminalEventIndexView(CriminalEvent selectedCriminalEvent = null)
{
CriminalEventMainViewModel viewModel =
new CriminalEventMainViewModel();
using (var db1 = new AIM.Police.DB.InvestigationContext(lazyLoadingEnabled: false))
{
viewModel.CriminalEvents = db1.CriminalEvents.Cast<ViewCriminalEvent>().ToList(); //THIS LINE THROWS THE EXCEPTION
viewModel.SelectedEntity = selectedCriminalEvent;
}
return View("Index", (object)viewModel);
}
Beachten Sie, dass die original - CriminalEvent
Klasse und die InvestigationContext
gefunden werden, in das ZIEL.Polizei.DB-dll, die ich nicht berühren kann
Den Fehler:
Unable to cast the type 'AIM.Police.DB.CriminalEvent' to type 'InvestigationSimulator.Models.CriminalEvent'. LINQ to Entities only supports casting EDM primitive or enumeration types.
Warum erhalte ich diese Fehlermeldung?
Bemerkungen zu meiner Vorgehensweise sind immer willkommen..
InformationsquelleAutor user1707621 | 2013-12-31
Du musst angemeldet sein, um einen Kommentar abzugeben.
Da bist du immer alle Entitäten, könnten Sie materialisieren sich erst die Abfrage, und führen Sie dann den cast.
Diese durchführen würde die Besetzung im Speicher, anstatt zu versuchen, es zu formulieren als Teil des query-übersetzung. Der Fehler kommt, weil LINQ to Entities nicht unterstützt, ist die Umwandlung der SQL, um eine nicht-entity-Klasse, auch wenn es erbt von einer entity-Klasse, denn es gibt keine Zuordnung für die zusätzlichen Spalten an, die
SELECT
- Anweisung. Durch die Materialisierung der Daten, dann die Durchführung derCast
im Speicher (LINQ to Objects), vermeiden Sie die übersetzung Fehler.Jedoch in Ihrem Fall, Sie haben die erbschaft nach hinten für diese zu arbeiten. Für Sie zu arbeiten, würde ich vorschlagen, dass die DB-Modell umzusetzen
IDataModel
vermeiden und die Besetzung komplett, siehe http://msdn.microsoft.com/en-us/library/vstudio/bb738696(v=vs. 100).aspx und http://msdn.microsoft.com/en-us/library/wa80x488.aspx. Insbesondere die partielle Klasse kann das interface implementieren (ehrlich gesagt erinnere mich nicht, wenn der designer ermöglicht Ihnen das hinzufügen einer definition der Schnittstelle, da ich nur code-first-in diesen Tagen). Beachten Sie, dass möglicherweise entfernen Sie die Notwendigkeit für Ihre Ansicht-spezifische Modell völlig.Die alternative, was würde ich wohl tun, ist, halten Sie view-Modell komplett getrennt (habe es nicht Erben von der entity-Klasse) und AutoMapper verwenden, um die Zuordnung zwischen Ihnen.
InvalidCastException
?AIM.Police.DB.CriminalEvent
nicht ableiten ausInvestigationSimulator.Models.CriminalEvent
. Die Frage ist nicht klar (zweiCriminalEvent
Klassen in verschiedenen namespaces, und der code, mit unqualifizierten Referenzen, ohne dass dasusing
namespaces), aber ich denke, dass EF so konfiguriert wird, zurückAIM.Police.DB.CriminalEvent
- und in diesem Fall, es will einfach nicht funktionieren.Ich interpretierte die Besetzung als in die andere Richtung aus dem DB-Modell an den view-Modell. Es ist wirklich nicht Sinn machen jede andere Art und Weise. In diesem Fall wird die view Modell ist abgeleitet aus dem DB-Modell. Die Fehlermeldung scheint sich zu verstärken. Es ist eine schlechte Praxis ist, IMO, haben die Klassen den gleichen Namen. In meinem Automapper Beispiel, ich führte eine unterschiedliche Namensgebung für die Ansicht Modell, um die Unterscheidung klarer.
Ich bin auch interpretieren als die vom DB-Modell an die view-Modell-aber ob das von base abgeleitet ist, funktioniert es nicht. Vereinbart, dass Ihr AutoMapper Ansatz ist wahrscheinlich besser.
wow - muss nicht sein denken. Du hast absolut Recht. Ich war gerade versucht zu lösen, die spezifische Fehler. Der Erbe muss gehen, der in die andere Richtung auch. Ich werde es in Ordnung bringen.
Sorry für die unklare code, der Erbe ist aus dem DB-Modell an den view-Modell und der code ist
Using
view-Modell der namespace-und so ist jede Erwähnung vonCriminalEvent
(außer wo explizit angegebenAIM.Police.DB
). Ich werde aktualisieren Sie den code oben...InformationsquelleAutor tvanfosson
Enumerable.Cast<TResult>
versucht zu casten jedes element in der Auflistung. Und es schlägt in Ihrem Szenario (keine überraschung), da Sie versuchen, zu werfen Instanzen Eltern (AIM.Police.DB.CriminalEvent
- ) Klasse Objekte von Kind (InvestigationSimulator.Models.CriminalEvent
) Klasse. Man kann nicht eine solche Umwandlung in C#.Um dieses Problem zu beheben, benötigen Sie zum laden von Objekten aus der DB zuerst und dann konvertieren (Karte), Sie manuell zu Ihrer Model-Klasse. Einfachste code ist wie folgt:
ToList().Select(...)
im wesentlichen unnötig erstellt eine Liste für eine einzelne Aufzählung. Es sollte wohl entwederToList().ConvertAll(...)
oderAsEnumerable().Select(...)
. (Das Ergebnis von allen drei wird die gleiche, nur die Art und Weise Sie das Ergebnis unterscheidet sich.)Ich gebe zu, ich wusste nicht, Casting funktioniert nur, Kind -> Eltern-und nicht Umgekehrt, ja, ich denke, ich kann nicht vermeiden das mapping, richtig? Die init der
Id
prop in Ihrer Einfachsten Code soll als Beispiel und sollte getan werden für alle Eigenschaften der Eltern?Ja, Sie haben Recht, das ist nur ein Beispiel, sollten Sie init alle Eigenschaften, die Sie brauchen, gibt es (nur durch Komma getrennt). Beachten Sie, dass Ihre Eigenschaften im Modell kann verschiedene Namen/Typ definieren Sie den mapping-Regeln in der Weise, die Ihnen am besten passt. Es gibt keine Notwendigkeit, Ihre Erben CriminalEvent Model-Klasse von DB. Nur definieren Sie Eigenschaften, die Sie wirklich brauchen, in Ihrer app und Karte, nur die von DB.
Casting bei Typ-Vererbung funktioniert entweder Richtung. Es führt zu einem Laufzeitfehler, wenn das Objekt passiert, nicht das Kind.
InformationsquelleAutor SergeyS
Verwenden Sie cast nach ToList() oder Single()
_c.Customers.ToList<CustomerBinding>()
InformationsquelleAutor Oswaldo Alvarez