Ich habe eine vorhandene Datenbank, mit der ich eine neue App erstellen möchte EF4.0
In einigen Tabellen sind keine Primärschlüssel definiert, sodass beim Erstellen eines neuen Entitätsdatenmodells die folgende Meldung angezeigt wird:
The table/view TABLE_NAME does not have a primary key defined
and no valid primary key could be inferred. This table/view has
been excluded. To use the entity, you will need to review your schema,
add the correct keys, and uncomment it.
Wenn ich sie verwenden und Daten ändern möchte, muss ich diesen Tabellen unbedingt eine PK hinzufügen, oder gibt es eine Problemumgehung, damit ich nicht muss?
.net
entity-framework
Krise
quelle
quelle
Antworten:
Der Fehler bedeutet genau das, was er sagt.
Selbst wenn Sie das umgehen könnten, vertrauen Sie mir, Sie wollen nicht. Die Anzahl der verwirrenden Fehler, die eingeführt werden könnten, ist erschütternd und beängstigend, ganz zu schweigen von der Tatsache, dass Ihre Leistung wahrscheinlich in die Knie gehen wird.
Umgehe das nicht. Korrigieren Sie Ihr Datenmodell.
EDIT: Ich habe gesehen, dass eine Reihe von Leuten diese Frage ablehnen. Das ist in Ordnung, nehme ich an, aber denken Sie daran, dass das OP nach der Zuordnung einer Tabelle ohne Primärschlüssel und nicht nach einer Ansicht gefragt hat . Die Antwort ist immer noch dieselbe. Unter dem Gesichtspunkt der Verwaltbarkeit, Datenintegrität und Leistung ist es eine schlechte Idee, die Notwendigkeit der EF zu umgehen, eine PK für Tabellen zu haben.
Einige haben kommentiert, dass sie das zugrunde liegende Datenmodell nicht reparieren können, da sie einer Drittanbieteranwendung zugeordnet sind. Das ist keine gute Idee, da sich das Modell unter Ihnen ändern kann. In diesem Fall möchten Sie wahrscheinlich eine Ansicht zuordnen, was wiederum nicht das ist, was das OP verlangt hat.
quelle
Ich denke, das wird von Tillito gelöst:
Entity Framework und SQL Server-Ansicht
Ich werde seinen Eintrag unten zitieren:
Wir hatten das gleiche Problem und dies ist die Lösung:
Verwenden Sie ISNULL, um das Entity Framework zu zwingen, eine Spalte als Primärschlüssel zu verwenden.
Verwenden Sie NULLIF, um zu erzwingen, dass das Entity Framework keine Spalte als Primärschlüssel verwendet.
Eine einfache Möglichkeit, dies anzuwenden, besteht darin, die select-Anweisung Ihrer Ansicht in eine andere select-Anweisung zu verpacken.
Beispiel:
beantwortet 26. April 10 um 17:00 von Tillito
quelle
Wenn Sie diese Frage beantworten und Entity Framework Core verwenden, müssen Sie diesen Tabellen nicht mehr unbedingt eine PK hinzufügen oder eine Problemumgehung durchführen. Seit EF Core 2.1 haben wir eine neue Funktion für Abfragetypen
Abfragetypen müssen verwendet werden für:
Fügen Sie in Ihrem DbContext einfach die folgende Eigenschaft vom Typ hinzu,
DbQuery<T>
anstattDbSet<T>
wie unten beschrieben. Angenommen, Ihr Tabellenname lautetMyTable
:quelle
Zusammengesetzte Schlüssel können auch mit der Entity Framework Fluent API erstellt werden
quelle
modelBuilder.Entity<T>()
Kettenaufruf mit.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
diesen ach so speziellen Schlüsseln versehen, die nicht natürlich oder zusammengesetzt sind, aber als verlässlich angesehen werden können auf einzigartig zu sein (normalerweise sowieso.)In meinem Fall musste ich eine Entität einer Ansicht zuordnen, die keinen Primärschlüssel hatte. Außerdem durfte ich diese Ansicht nicht ändern. Glücklicherweise hatte diese Ansicht eine Spalte, die eine eindeutige Zeichenfolge war. Meine Lösung bestand darin, diese Spalte als Primärschlüssel zu markieren:
Betrogene EF. Hat perfekt funktioniert, niemand hat es bemerkt ... :)
quelle
UserID
Spalte erstellt, wenn Sie den Code First-Ansatz verwenden ..!Itentity
Funktion auszuschalten . Wenn ich richtig liege, wird im Grunde immer noch eineUserID
Spalte für Sie als PK erstellt, aber die wird nicht automatisch erhöht,UserID
wenn Sie einen neuen Datensatz erstellen, wie dies standardmäßig der Fall wäre. Außerdem müssen Sie immer noch unterschiedliche Werte beibehaltenUserID
.EF benötigt keinen Primärschlüssel in der Datenbank. In diesem Fall konnten Sie keine Entitäten an Ansichten binden.
Sie können die SSDL (und die CSDL) ändern, um ein eindeutiges Feld als Primärschlüssel anzugeben. Wenn Sie kein einzigartiges Feld haben, dann glaube ich, dass Sie abgespritzt sind. Aber Sie sollten wirklich ein eindeutiges Feld (und eine PK) haben, sonst werden Sie später auf Probleme stoßen.
Erick
quelle
Einen nutzlosen Identitätsschlüssel zu haben ist manchmal sinnlos. Ich finde, wenn die ID nicht verwendet wird, warum sie hinzufügen? Entity verzeiht dies jedoch nicht so sehr, daher ist es am besten, ein ID-Feld hinzuzufügen. Selbst wenn es nicht verwendet wird, ist es besser, als sich mit den unaufhörlichen Fehlern von Entity bezüglich des fehlenden Identitätsschlüssels zu befassen.
quelle
DIESE LÖSUNG FUNKTIONIERT
Sie müssen nicht manuell zuordnen, auch wenn Sie keine PK haben. Sie müssen dem EF nur mitteilen, dass eine Ihrer Spalten Index ist und die Indexspalte nicht nullwertfähig ist.
Dazu können Sie Ihrer Ansicht eine Zeilennummer mit der folgenden isNull-Funktion hinzufügen
ISNULL(id, number)
ist hier der entscheidende Punkt, da er dem EF mitteilt, dass diese Spalte ein Primärschlüssel sein kannquelle
Die obigen Antworten sind richtig, wenn Sie wirklich keine PK haben.
Wenn es jedoch einen gibt, der jedoch nicht mit einem Index in der Datenbank angegeben ist und Sie die Datenbank nicht ändern können (ja, ich arbeite in Dilberts Welt), können Sie die Felder manuell als Schlüssel zuordnen.
quelle
Dies ist nur eine Ergänzung zu @Erick T's Antwort. Wenn es keine einzelne Spalte mit eindeutigen Werten gibt, besteht die Problemumgehung darin, einen zusammengesetzten Schlüssel wie folgt zu verwenden:
Auch dies ist nur eine Problemumgehung. Die wirkliche Lösung besteht darin, das Datenmodell zu reparieren.
quelle
Dies ist vielleicht zu spät, um zu antworten ... aber ...
Wenn eine Tabelle keinen Primärschlüssel hat, müssen nur wenige Szenarien analysiert werden, damit die EF ordnungsgemäß funktioniert. Die Regel lautet: EF arbeitet mit Tabellen / Klassen mit Primärschlüssel. So macht es Tracking ...
Angenommen, Ihre Tabelle 1. Datensätze sind eindeutig: Die Eindeutigkeit wird durch eine einzelne Fremdschlüsselspalte festgelegt: 2. Datensätze sind eindeutig: Die Eindeutigkeit wird durch eine Kombination mehrerer Spalten erstellt. 3. Datensätze sind nicht eindeutig (größtenteils *).
Für die Szenarien 1 und 2 können Sie der OnModelCreating-Methode des DbContext-Moduls die folgende Zeile hinzufügen: modelBuilder.Entity (). HasKey (x => new {x.column_a, x.column_b}); // so viele Spalten wie nötig, um Datensätze eindeutig zu machen.
Für das Szenario Nr. 3 können Sie nach dem Studium der Tabelle weiterhin die oben genannte Lösung (Nr. 1 + Nr. 2) verwenden (* was alle Datensätze sowieso einzigartig macht). Wenn Sie ALLE Spalten einschließen müssen, um alle Datensätze eindeutig zu machen, möchten Sie möglicherweise eine Primärschlüsselspalte zu Ihrer Tabelle hinzufügen. Wenn diese Tabelle von einem Drittanbieter stammt, klonen Sie diese Tabelle in Ihre lokale Datenbank (über Nacht oder so oft wie nötig), wobei die Primärschlüsselspalte über Ihr Klonskript beliebig hinzugefügt wird.
quelle
Entity Framework: Hinzufügen einer Datentabelle ohne Primärschlüssel zum Entitätsmodell.
quelle
Update auf @CodeNotFound die Antwort .
In EF Core 3.0
DbQuery<T>
ist veraltet, stattdessen sollten Sie Keyless-Entitätstypen verwenden, die angeblich dasselbe tun. Diese werden mit der ModelBuilder-HasNoKey()
Methode konfiguriert . Führen Sie dies in Ihrer DbContext-Klasse ausEs gibt jedoch Einschränkungen, insbesondere:
Dies bedeutet, dass für die Frage von
Sie können Daten auf diese Weise nicht ändern - Sie können sie jedoch lesen. Man könnte sich jedoch vorstellen, eine andere Methode (z. B. ADO.NET, Dapper) zu verwenden, um Daten zu ändern - dies könnte eine Lösung in Fällen sein, in denen Sie selten nicht gelesene Vorgänge ausführen müssen und in den meisten Fällen dennoch bei EF Core bleiben möchten.
Wenn Sie wirklich mit Heap-Tabellen (ohne Schlüssel) arbeiten müssen / möchten, sollten Sie EF in den Hintergrund rücken und auf andere Weise mit Ihrer Datenbank kommunizieren.
quelle
Aus praktischer Sicht sollte jede Tabelle - selbst eine denormalisierte Tabelle wie eine Lagertabelle - einen Primärschlüssel haben. Andernfalls sollte es mindestens einen eindeutigen, nicht nullwertfähigen Index haben.
Ohne einen eindeutigen Schlüssel können (und werden) doppelte Datensätze in der Tabelle angezeigt werden, was sowohl für ORM-Ebenen als auch für das grundlegende Verständnis der Daten sehr problematisch ist. Eine Tabelle mit doppelten Datensätzen ist wahrscheinlich ein Symptom für schlechtes Design.
Zumindest sollte die Tabelle mindestens eine Identitätsspalte haben. Das Hinzufügen einer automatisch generierenden ID-Spalte dauert in SQL Server ca. 2 Minuten und in Oracle ca. 5 Minuten. Für diesen zusätzlichen Aufwand werden viele, viele Probleme vermieden.
quelle
Wir sind auch auf dieses Problem gestoßen, und obwohl wir eine Spalte mit Nullen hatten, war es wichtig, dass wir eine abhängige Spalte hatten, die keine Nullen hatte, und dass die Kombination dieser beiden Spalten eindeutig war.
Um die Antwort von Pratap Reddy zu zitieren, hat es für uns gut funktioniert.
quelle
Ich bin sehr froh, dass mein Problem gelöst ist.
Das EntitySet kann nicht aktualisiert werden, da es eine DefiningQuery enthält und kein <UpdateFunction> -Element vorhanden ist
und tun Sie dies: Schauen Sie unter diese Zeile und finden Sie das Tag. Es wird eine große alte select-Anweisung enthalten. Entfernen Sie das Tag und seinen Inhalt.
Jetzt kann DB TI ohne Änderung in eine Tabelle einfügen, die keine PK hat
Danke an alle und danke an Pharylon
quelle
In EF Core 5.0 können Sie es auch auf Entitätsebene definieren.
Referenz: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/whatsnew#use-ac-attribute-to-indicate-that-an-entity- hat-keinen-Schlüssel
quelle
Die Tabelle muss nur eine Spalte enthalten, die keine Nullen zulässt
quelle