it-swarm.com.de

Das EntitySet kann nicht aktualisiert werden, da es ein DefiningQuery-Element und kein <UpdateFunction> -Element enthält

Ich verwende Entity Framework 1 mit .net 3.5.

Ich mache etwas so einfaches:

var RoomDetails = context.Rooms.ToList();

foreach (var Room in Rooms)
{        
   Room.LastUpdated = DateTime.Now;
}

Ich erhalte diese Fehlermeldung, wenn ich versuche zu tun:

 context.SaveChanges();

Ich bekomme den Fehler:

Update des EntitySet nicht möglich - weil es ein DefiningQuery-Element und kein <UpdateFunction> -Element im <ModificationFunctionMapping> -Element zur Unterstützung der aktuellen Operation enthält.

Ich mache viele Updates im Kontext und habe keine Probleme, nur wenn ich versuche, diese bestimmte Entität zu aktualisieren.

Alle meine Suchvorgänge zeigen dasselbe, dass für die Entität, die ich aktualisieren möchte, kein Primärschlüssel deklariert ist. Aber leider habe ich einen Primärschlüssel deklariert ...

478
iKode

Dies geschieht normalerweise aus einem der folgenden Gründe:

  • Entity Set wird aus der Datenbankansicht zugeordnet
  • Eine benutzerdefinierte Datenbankabfrage
  • Datenbanktabelle hat keinen Primärschlüssel

Danach müssen Sie möglicherweise noch eine Aktualisierung im Entity Framework-Designer durchführen (oder alternativ die Entität löschen und dann hinzufügen), bevor Sie den Fehler abbrechen.

928
Ladislav Mrnka

Fügen Sie einfach einen Primärschlüssel zur Tabelle hinzu. Das ist es. Problem gelöst.

ALTER TABLE <TABLE_NAME>
ADD CONSTRAINT <CONSTRAINT_NAME> PRIMARY KEY(<COLUMN_NAME>)
82
Jebastin J

Das ist bei mir der Fall. Das einfache Entfernen führte zu einem anderen Fehler. Ich habe die Schritte dieses Beitrags mit Ausnahme des letzten verfolgt. Zu Ihrer Bequemlichkeit kopierte ich die 4 Schritte aus dem Beitrag, den ich befolgte, um das Problem wie folgt zu lösen:

  1. Klicken Sie mit der rechten Maustaste auf die edmx-Datei und wählen Sie Öffnen mit XML-Editor
  2. Suchen Sie die Entität im edmx: StorageModels-Element
  3. Entfernen Sie die DefiningQuery vollständig
  4. Benennen Sie store:Schema="dbo" in Schema="dbo" um (andernfalls generiert der Code eine Fehlermeldung, dass der Name ungültig ist)
51
kavitha Reddy

Beachten Sie, dass Ihr Entity vielleicht Primärschlüssel hat aber Ihre Tabelle in der Datenbank keinen Primärschlüssel hat. 

38
Majid

UPDATE: Ich habe in letzter Zeit ein paar Upvotes dazu bekommen, also dachte ich, ich würde die Leute wissen lassen, dass der Rat, den ich unten gebe, nicht der beste ist. Seit ich anfing, mit Entity Framework auf alten schlüssellosen Datenbanken herumzuspielen, habe ich erkannt, dass das Beste, was Sie mit Abstand tun können, die Verwendung von Reverse-Code-First ist. Es gibt ein paar gute Artikel darüber, wie das geht. Folgen Sie ihnen, und wenn Sie dann einen Schlüssel hinzufügen möchten, verwenden Sie Datenanmerkungen, um den Schlüssel zu "fälschen". 

Nehmen wir beispielsweise an, ich kenne meine Tabelle Orders, die zwar keinen Primärschlüssel hat, aber sicher ist, dass pro Kunde immer nur eine Bestellnummer vorhanden ist. Da dies die ersten beiden Spalten in der Tabelle sind, würde ich die ersten Klassen des Codes so einrichten, dass sie folgendermaßen aussehen:

    [Key, Column(Order = 0)]
    public Int32? OrderNumber { get; set; }

    [Key, Column(Order = 1)]
    public String Customer { get; set; }

Auf diese Weise haben Sie EF im Grunde vorgetäuscht, zu glauben, es gebe einen zusammengesetzten Schlüssel, bestehend aus Bestellnummer und Kunde. Auf diese Weise können Sie Einfügungen, Aktualisierungen usw. an Ihrer schlüssellosen Tabelle vornehmen.

Wenn Sie mit Reverse Code First nicht zu sehr vertraut sind, finden Sie ein gutes Tutorial zu Entity Framework Code First. Dann gehen Sie zu Reverse Code First (finden Sie Code First mit einer vorhandenen Datenbank). Dann kommen Sie einfach hierher zurück und sehen Sie sich meine wichtigsten Ratschläge noch einmal an. :)

Ursprüngliche Antwort :

Erstens: Wie bereits gesagt, besteht die beste Option darin, der Tabelle einen Primärschlüssel hinzuzufügen. Punkt. Wenn Sie dies tun können, lesen Sie nicht weiter.

Wenn Sie es nicht können oder einfach nur hassen, gibt es eine Möglichkeit, dies ohne den Primärschlüssel zu tun.

In meinem Fall arbeitete ich mit einem Altsystem (ursprünglich flache Dateien auf einem AS400, der auf Access und dann auf T-SQL portiert wurde). Also musste ich einen Weg finden. Das ist meine Lösung. Die folgenden Arbeiten funktionierten für mich mit Entity Framework 6.0 (das neueste von NuGet zum Zeitpunkt der Veröffentlichung).

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf Ihre EDMX-Datei. Wählen Sie "Öffnen mit ..." und anschließend "XML (Text) Editor". Wir werden den automatisch generierten Code hier von Hand bearbeiten.

  2. Suchen Sie nach einer Zeile wie dieser: 
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">

  3. Entfernen Sie store:Name="table_name" vom Ende.

  4. store:Schema="whatever" in Schema="whatever" ändern

  5. Schauen Sie unter dieser Zeile nach dem <DefiningQuery>-Tag. Es wird eine große ol 'select-Anweisung enthalten. Entfernen Sie das Tag und seinen Inhalt.

  6. Jetzt sollte Ihre Zeile ungefähr so ​​aussehen: 
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />

  7. Wir haben noch etwas zu ändern. Durchsuchen Sie Ihre Datei und finden Sie Folgendes:
    <EntityType Name="table_name">

  8. In der Nähe werden Sie wahrscheinlich einen kommentierten Text sehen, der Sie warnt, dass kein Primärschlüssel identifiziert wurde. Daher wurde der Schlüssel abgeleitet und die Definition ist eine schreibgeschützte Tabelle/Ansicht. Sie können es verlassen oder löschen. Ich habe es gelöscht.

  9. Unten ist das <Key>-Tag. Dies wird von Entity Framework zum Einfügen/Aktualisieren/Löschen verwendet. SO Stellen Sie sicher, dass Sie dies richtig machen. Die Eigenschaft (oder Eigenschaften) in diesem Tag müssen eine eindeutig identifizierbare Zeile angeben. Nehmen wir beispielsweise an, ich kenne meine Tabelle orders, die zwar keinen Primärschlüssel hat, aber sicher ist, dass pro Kunde immer nur eine Bestellnummer vorhanden ist. 

So sieht mein aus:

<EntityType Name="table_name">
              <Key>
                <PropertyRef Name="order_numbers" />
                <PropertyRef Name="customer_name" />
              </Key>

Ernsthaft, mach das nicht falsch. Nehmen wir an, dass, obwohl es niemals Duplikate geben sollte, irgendwie zwei Reihen mit derselben Bestellnummer und demselben Kundennamen in mein System gelangen. Whooops! Das ist es, was ich bekomme, wenn ich keinen Schlüssel verwende! Also verwende ich Entity Framework, um eines zu löschen. Da ich weiß, dass das Duplikat heute die einzige Bestellung ist, mache ich Folgendes:

var duplicateOrder = myModel.orders.First(x => x.order_date == DateTime.Today);
myModel.orders.Remove(duplicateOrder);

Erraten Sie, was? Ich habe nur das Duplikat UND das Original gelöscht! Das liegt daran, dass ich Entity Framework mitteilte, dass order_number/cutomer_name mein Primärschlüssel war. Als ich ihm sagte, dass Du duplicateOrder entfernen solltest, war das im Hintergrund so etwas:

DELETE FROM orders
WHERE order_number = (duplicateOrder's order number)
AND customer_name = (duplicateOrder's customer name)

Und mit dieser Warnung ... solltest du jetzt gut sein!

29
Pharylon

Dies kann auch passieren, wenn das Datenmodell nicht mehr aktuell ist.

Hoffentlich erspart sich jemand anderes die Frustration :)

18
mob1lejunkie

Ich habe dieselbe Fehlermeldung erhalten, aber in meinem Szenario habe ich versucht, Entitäten zu aktualisieren, die aus einer Many-to-Many-Beziehung mit einer PJT (Pure Join Table) abgeleitet wurden.

Nachdem ich die anderen Beiträge gelesen hatte, dachte ich, ich könnte das Problem beheben, indem ich der Join-Tabelle ein zusätzliches PK-Feld hinzufüge. Wenn Sie jedoch einer Join-Tabelle eine PK-Spalte hinzufügen, ist dies kein PJT mehr und Sie verlieren alle Vorteile des Entity-Frameworks wie die automatische Zuordnung von Beziehungen zwischen den Entitäten.

In meinem Fall bestand die Lösung darin, die Join-Tabelle in der DB so zu ändern, dass ein PK erstellt wird, der BEIDE der Fremd-ID-Spalten enthält.

6
Kerry Randolph

ein Fehler kann auftreten, wenn Ihre Tabelle keinen Primärschlüssel hat. In diesem Fall ist die Tabelle "Nur Lesen" und der Befehl db.SaveChanges () wird immer einen Fehler anzeigen

4
Ruben.sar

so ist es wahr, einfach einen Primärschlüssel hinzufügen

Hinweis: Stellen Sie sicher, dass beim Aktualisieren Ihres EF-Diagramms aus der Datenbank, die Sie auf die Datenbank " right " zeigen, die Verbindungszeichenfolge in meinem Fall auf eine lokale Datenbank statt auf das Up-to-Objekt verweist -date Dev DB, Schülerfehler Ich weiß, aber ich wollte das hier posten, weil es sehr frustrierend sein kann, wenn Sie überzeugt sind, dass Sie den Primärschlüssel hinzugefügt haben und immer noch den gleichen Fehler erhalten. 

3
Spyder

Ich hatte das gleiche Problem. Wie in diesem Thread gesagt, hatte meine Tabelle keinen PK, also habe ich den PK eingestellt und den Code ausgeführt. Aber leider kam wieder ein Fehler. Als nächstes habe ich die DB-Verbindung gelöscht (.edmx-Datei im Modellordner des Projektmappen-Explorers löschen) und neu erstellt. Fehler danach gegangen. Vielen Dank an alle für Ihre Erfahrungen. Das spart viel Zeit.

2
Namal

Legen Sie den Primärschlüssel fest, speichern Sie die Tabelle und aktualisieren Sie sie, und wechseln Sie zu Model.edmx delete Table.

1
Joan Ali

Ich habe dieses Problem erhalten, weil ich mein EDMX aus einer vorhandenen Datenbank (die von einem anderen Benutzer erstellt wurde) generierte und ich hier den Begriff "entworfen" verwende.

Es stellte sich heraus, dass der Tisch keinerlei Schlüssel hatte. EF hat das Modell mit vielen mehreren Schlüsseln erstellt. Ich musste der DB-Tabelle in SQL einen Primärschlüssel hinzufügen und dann mein Modell in VS aktualisieren. 

Das hat es für mich behoben.

1
Stark

Ich musste nur die Tabelle aus dem Modell entfernen und das Modell erneut aktualisieren, um die Tabelle wieder herzustellen. Ich denke, der Primärschlüssel wurde erstellt, nachdem die Tabelle in das Modell gezogen wurde.

0
dangalg

Ich hatte genau das gleiche Problem. Leider kann das Problem durch das Hinzufügen des Primärschlüssels nicht gelöst werden. So löse ich meine:

  1. Stellen Sie sicher, dass Sie einen primary key in der Tabelle haben, damit ich meine Tabelle ändere und einen Primärschlüssel hinzufüge.
  2. Delete the ADO.NET Entity Data Model (edmx-Datei), mit dem ich meine Datenbank abbilden und verbinden kann.
  3. Add again a new file of ADO.NET Entity Data Model, um eine Verbindung mit meiner Datenbank herzustellen und meine Modelleigenschaften abzubilden.
  4. Clean and rebuild the solution. 

Problem gelöst.

0
Willy David Jr

Das Hinzufügen des Primärschlüssels hat auch für mich funktioniert!

Anschließend können Sie das Datenmodell aktualisieren, ohne es zu löschen.

Klicken Sie mit der rechten Maustaste auf die Designer-Seite von edmx Entity und auf 'Update Model from Database'.

0

Öffnen Sie Ihre .edmx-Datei im XML-Editor, entfernen Sie das Tag aus Tag und ändern Sie auch den Speicher: Schema = "dbo" in Schema = "dbo".

0
Sharad Tiwari

fügen Sie einfach einen Primärschlüssel zu Ihrer Tabelle hinzu und erstellen Sie dann Ihre EF neu

0
Sulyman

Ich hatte dieses Problem aufgetaucht und glaube, es liegt daran, dass ich den Index für den Primärschlüssel meiner Tabellen gelöscht und durch einen Index für einige der anderen Felder in der Tabelle ersetzt habe.

Nachdem ich den Primärschlüsselindex gelöscht und den edmx aktualisiert hatte, funktionierten die Inserts nicht mehr. 

Ich habe die Tabelle auf die ältere Version aktualisiert, den edmx aktualisiert und alles funktioniert wieder. 

Ich sollte beachten, dass beim Öffnen des EDMX zur Behebung dieses Problems die Überprüfung, ob ein Primärschlüssel definiert wurde, vorhanden war. Also half mir keiner der obigen Vorschläge. Die Aktualisierung des Index für den Primärschlüssel schien jedoch zu funktionieren.

0
armstb01

Dies ist keine neue Antwort, hilft jedoch jemandem, der nicht sicher ist, wie er den Primärschlüssel für seine Tabelle festlegen soll. Verwenden Sie dies in einer neuen Abfrage und führen Sie es aus. Dadurch wird die UniqueID-Spalte als Primärschlüssel festgelegt.

USE [YourDatabaseName]
GO

Alter table  [dbo].[YourTableNname]
Add Constraint PK_YourTableName_UniqueID Primary Key Clustered (UniqueID);
GO
0
JessS