DbSet.FirstOrDefault()?
Ich versuche dies zu tun, aber es sagt, dass ich nicht verwenden können, FirstOrDefault,
public static int GetId(this Context db, Type type, string name)
{
return db.Set(type).FirstOrDefault(x => x.Name == name).Id;
}
Den Fehler 'System.Daten.Entität.DbSet "enthält keine definition für "FirstOrDefault" und keine Erweiterung Methode "FirstOrDefault" die Akzeptanz der ein erstes argument vom Typ 'System.Daten.Entität.DbSet' gefunden werden konnte (fehlt eine using-Direktive oder ein Assemblyverweis?)
Dann habe ich versucht, dieses Cast
Methode, aber das war ein Fehler Nicht DbSet von einer nicht-generischen DbSet für Objekte vom Typ 'WindowStyle' (btw WindowStyle
erbt von DomainEntity
unten),
var set = db.Set(type).Cast<DomainEntity>();
return set.FirstOrDefault(x => x.Name == name).Id;
Hier ist die Klasse,
public class DomainEntity
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
Sie haben
Ist dein zweiter Fehler (
ja, habe ich. Gute Frage.
Es wurde Zeit, zeigt sich in meinem browser.
using System.Linq
am Anfang der Datei? DbSet erbt IEnumerable aber die LINQ-Funktionen sind alle Extension-Methoden und wird nicht verfügbar sein, ohne die using-Anweisung.Ist dein zweiter Fehler (
Cast
) einen Kompilier-oder Laufzeitfehler? Das wird einen großen Unterschied machen, und es ist schwer, Rückschlüsse auf Ihre Frage.ja, habe ich. Gute Frage.
Es wurde Zeit, zeigt sich in meinem browser.
InformationsquelleAutor Benjamin | 2011-11-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Diese Antwort möglicherweise nicht helfen, Sie abhängig davon, wie "dynamisch" die situation ist, wo diese Methode aufgerufen wird, im Grunde, wenn Sie wissen, den Typ zur compile-Zeit oder nicht. Wenn Sie es wissen schreiben Sie eine generische Methode statt:
Ich habe es geändert, eine Projektion, weil Sie nicht brauchen, um zu laden, die volle Einheit, wenn Sie möchten, dass nur die Id. Lassen Sie die Datenbank die Arbeit zu tun, wählen Sie die Eigenschaft, um die Leistung zu verbessern ein bisschen. Auch habe ich wieder eine null-int im Falle, dass es keine übereinstimmung für den Namen in der Datenbank.
Rufen Sie diese in Ihrem code etwa so:
Wie Sie sehen können, für diese Lösung müssen Sie den Typ angeben
WindowStyle
zur compile-Zeit.Dies setzt Voraus, dass
DomainEntity
ist nicht Teil des Modells (es gibt keineDbSet<DomainEntity>
), aber nur eine Basis-Klasse der Entitäten. Ansonsten @Paul Keiser, der die Lösung wäre einfacher.Bearbeiten
Alternativ können Sie auch Folgendes versuchen:
Und nennen es:
Wird es werfen eine Ausnahme, wenn zur Laufzeit, wenn
someType
erbt nicht vonDomainEntity
. Die generische version wird überprüfen Sie dies zur compile-Zeit. Also, wenn Sie kann bevorzuge die erste version.Wenn ich könnte Euch alle meinem Ruf hier, ich würde - das ist, was ich bin auf der Suche nach etwa einen halben Jahr, und ich kam immer falsche Ansatz. Thx, du bist echt mein Gott jetzt.
InformationsquelleAutor Slauma
Vielleicht sind Sie fehlen
Ich vergaß, stellen Sie sicher, dass System.Linq wurde in aufzuhalten der Benutzung! Es ist fast immer vorhanden standardmäßig, und ich hätte nie gedacht, um nach ihm zu suchen.
InformationsquelleAutor riseres
Das erste Konstrukt, das nicht funktionieren wird, weil Sie mit einer nicht-generischen DbSet, so können Sie nicht für die FirstOrDefault-Erweiterung-Methode, die funktioniert nur mit einem generischen. Es klingt wie Sie verstehen das schon, da hast du bereits versucht, um das nicht-generische DbSet. Der Fehler, den du immer mit der Cast () - Methode wird verursacht durch den Versuch aus ein DbSet zu einem DbSet. Dies kann nicht gestattet werden, denn wenn es waren, es wäre möglich, hinzufügen von nicht-konformen Mitgliedern der DbSet (Objekte vom Typ als WindowsStyle). Eine andere Weise dies zu sagen ist, dass die Kovarianz ist nicht unterstützt für DbSets weil DbSets erlauben Ergänzungen.
Ich denke, du musst einen anderen Weg finden, das zu tun, was Sie zu tun versuchen. Mischen LINQ und Vererbung diese Weise offensichtlich problematisch. Da haben Sie einen Basistyp definiert, und Sie arbeiten nur mit Attributen, die verfügbar sind auf der Basis geben, warum nicht einfach die Abfrage der base geben?
Sind Sie wahrscheinlich besorgt über Kollisionen mit Namen, die zwischen den verschiedenen Arten, aber wahrscheinlich können Sie beginnen, mit diesem und mit Blick auf den abgeleiteten Typ Verbände zu überprüfen, ob Sie suchen, im richtigen geben. Eine Möglichkeit, damit umzugehen, ist eine Art fahne, um Ihre DomainEntity definition.
Paul, Vielen Dank. Aber ich habe nicht ein
DbSet<DomainEntity>
auf dieDbContext
. Das ist, warum ich bin ein problem? Ich war gerade mitDomainEntity
zu organisieren, die anderen Klassen durch Vererbung. Ich denke, das eigentliche problem ist, ich verstehe nicht die Generika.Ich habe versucht, mit
MakeGenericType
aber es sagteDbSet<DomainEntity>
ist nicht ein generischer Typ.Die DbSet abrufen von Entitäten aus der Datenbank. Also, wenn Sie nicht über eine separate Datenbank-Tabelle für die DomainEntity Person dieser Ansatz wird scheitern. Mit der DB zunächst, dies kann definitiv getan werden. Es klingt wie Sie sind mit code zuerst; ich habe das noch nie getan mit dem ersten code, aber es sollte möglich sein. In jedem Fall müssen Sie eine DomainEntity DbSet. Auf der Datenbank-Seite, kann die Vererbung modelliert werden, indem der Primärschlüssel für die Entitäten abgeleitet auch ein Fremdschlüssel auf die id der übergeordneten Entität.
InformationsquelleAutor Paul Keister
Hier ist das Problem. Die
DbSet
Klasse hat seine eigene Implementierung vonCast<T>()
, erlaubt NUR die Datenbank-Typen (wieCast<WindowStyle>()
), so dass diese Methode nicht zulassenCast<DomainEntity>()
und wirft die Ausnahme.Statt, die Sie verwenden möchten die
IQueryable.Cast<T>()
Erweiterung Methode, die einfach nur gegossen werden Ihre Daten an die Basis geben. Hier ist ein Beispiel:InformationsquelleAutor Scott Rippey
Hier ist eine Idee, die ich hatte, das scheint zu funktionieren.
dynamic
mitDomainEntity
hier, die Ihnen fast die gleichen wie meine Antwort.Laden einer Tabelle in den Speicher (vielleicht 1 Mio Zeilen), um nur eine einzelne Id, sieht sehr uncool. Der start der Schleife wird die Abfrage auszuführen
set
mit keinen filter. Bleiben Sie Weg von dieser Lösung.außer, er gibt das Spiel nach Durchlaufen der gesamten Tabelle 🙂 post editiert.
InformationsquelleAutor Benjamin
Versuchen Rückwärtsfahren ein wenig
Ihnen wird eine null zurück Entität und dann versuchen, die Id aus.
Where
aber es hatte das gleiche problem wieFirstOrDefault
. Danke.Dies stellt ein problem zu lösen (unsachgemäße Verwendung von
FirstOrDefault
), aber es ist nicht in Bezug zu der Frage.InformationsquelleAutor Adam Tuliper - MSFT