602 Stimmen

EntitySet kann nicht aktualisiert werden, da es eine DefiningQuery hat und kein <UpdateFunction>-Element vorhanden ist

Ich verwende Entity Framework 1 mit .net 3.5.

Ich mache etwas Einfaches wie das hier:

var roomDetails = context.Rooms.ToList();

foreach (var room in roomDetails)
{        
   room.LastUpdated = DateTime.Now;
}

Ich erhalte diese Fehlermeldung, wenn ich versuche, dies zu tun:

 context.SaveChanges();

Ich erhalte die Fehlermeldung:

Das EntitySet kann nicht aktualisiert werden, weil es eine DefiningQuery hat und kein <UpdateFunction>-Element im <ModificationFunctionMapping>-Element vorhanden ist, um den aktuellen Vorgang zu unterstützen.

Ich führe viele Aktualisierungen im Kontext durch und habe keine Probleme, nur wenn ich versuche, diese bestimmte Entität zu aktualisieren.

Alle meine Suche zeigt die gleiche Sache, dass es keine Primärschlüssel auf die Entität, die ich versuche, zu aktualisieren deklariert ist. Aber ach, ich habe einen Primärschlüssel deklariert...

1120voto

Ladislav Mrnka Punkte 355028

Dies geschieht in der Regel aus einem der folgenden Gründe:

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

Nachdem Sie dies getan haben, müssen Sie möglicherweise immer noch im Entity Framework-Designer aktualisieren (oder alternativ die Entität löschen und sie dann hinzufügen), bevor der Fehler nicht mehr auftritt.

101voto

Jebastin J Punkte 1251

Fügen Sie der Tabelle einfach einen Primärschlüssel hinzu. Das war's. Problem gelöst.

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

77voto

kavitha Reddy Punkte 3203

Das ist bei mir der Fall. Einfaches Entfernen führte zu einem weiteren Fehler. Ich habe die Schritte in diesem Beitrag bis auf den letzten befolgt. Für Ihre Bequemlichkeit habe ich die 4 Schritte aus dem Beitrag kopiert, die ich befolgt habe, 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 Element edmx:StorageModels
  3. Entfernen Sie die DefiningQuery vollständig
  4. Umbenennen der store:Schema="dbo" a Schema="dbo" (andernfalls wird der Code eine Fehlermeldung ausgeben, die besagt, dass der Name ungültig ist)

49voto

Majid Punkte 12967

Beachten Sie einfach, dass vielleicht Ihr Entität haben Primärschlüssel sondern Ihre Tabelle in der Datenbank hat nicht Primärschlüssel .

36voto

Pharylon Punkte 9566

UPDATE: Ich habe in letzter Zeit ein paar positive Bewertungen zu diesem Thema erhalten, also dachte ich mir, ich lasse die Leute wissen, dass der Rat, den ich unten gebe, nicht der beste ist. Seit ich anfing, mit Entity Framework auf alten schlüssellosen Datenbanken herumzupfuschen, habe ich erkannt, dass das Beste, was Sie tun können, bei weitem ist, es durch Reverse-Code-First zu tun. Es gibt ein paar gute Artikel darüber, wie man das macht. Folgen Sie ihnen einfach, und wenn Sie dann einen Schlüssel hinzufügen möchten, verwenden Sie Datenanmerkungen, um den Schlüssel "vorzutäuschen".

Nehmen wir zum Beispiel an, ich kenne meine Tabelle Orders hat zwar keinen Primärschlüssel, aber es ist sichergestellt, dass es immer nur eine Bestellnummer pro Kunde gibt. Da dies die ersten beiden Spalten der Tabelle sind, würde ich die ersten Klassen des Codes so einrichten, dass sie wie folgt aussehen:

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

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

Auf diese Weise gaukeln Sie EF vor, dass es einen Cluster-Schlüssel gibt, der aus OrderNumber und Customer besteht. Dies ermöglicht Ihnen, Einfügungen, Aktualisierungen usw. in Ihrer schlüssellosen Tabelle vorzunehmen.

Wenn Sie nicht allzu vertraut mit Reverse Code First sind, suchen Sie ein gutes Tutorial über Entity Framework Code First. Dann suchen Sie nach einem Tutorial über Reverse Code First (was bedeutet, Code First mit einer bestehenden Datenbank durchzuführen). Dann kommen Sie einfach hierher zurück und sehen sich meine wichtigsten Ratschläge noch einmal an :)

Original-Antwort :

Erstens: Wie bereits von anderen gesagt, ist es am besten, der Tabelle einen Primärschlüssel hinzuzufügen. Punktum. Wenn Sie dies tun können, lesen Sie nicht weiter.

Aber wenn Sie das nicht können oder sich selbst hassen, gibt es einen Weg, es ohne den Primärschlüssel zu tun.

In meinem Fall habe ich mit einem Altsystem gearbeitet (ursprünglich flache Dateien auf einer AS400, die nach Access und dann nach T-SQL portiert wurden). Also musste ich einen Weg finden. Dies ist meine Lösung. Das Folgende funktionierte für mich mit Entity Framework 6.0 (die neueste Version von NuGet zum Zeitpunkt dieses Schreibens).

  1. Klicken Sie mit der rechten Maustaste auf Ihre .edmx-Datei im Projektmappen-Explorer. Wählen Sie "Öffnen mit..." und dann "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 store:Name="table_name" vom Ende her.

  4. Ändern Sie store:Schema="whatever" a Schema="whatever"

  5. Schauen Sie unter diese Zeile und suchen Sie die <DefiningQuery> Tag. Darin befindet sich eine große Select-Anweisung. Entfernen Sie das Tag und seinen Inhalt.

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

  7. Wir haben noch etwas anderes zu ändern. Gehen Sie durch Ihre Datei und finden Sie dies:
    <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, so dass der Schlüssel abgeleitet wurde und die Definition eine schreibgeschützte Tabelle/Ansicht ist. Sie können es dabei belassen oder es löschen. Ich habe ihn gelöscht.

  9. Nachstehend finden Sie die <Key> Tag. Dies ist das, was Entity Framework verwenden wird, um Einfügungen/Aktualisierungen/Löschungen durchzuführen. STELLEN SIE ALSO SICHER, DASS SIE DIES RICHTIG MACHEN. Die Eigenschaft (oder Eigenschaften) in diesem Tag müssen eine eindeutig identifizierbare Zeile angeben. Sagen wir zum Beispiel, ich kenne meine Tabelle orders hat zwar keinen Primärschlüssel, aber es ist sichergestellt, dass es immer nur eine Bestellnummer pro Kunde gibt.

So sieht meine aus:

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

Im Ernst, machen Sie das nicht falsch. Angenommen, obwohl es keine Duplikate geben sollte, gelangen irgendwie zwei Zeilen mit derselben Bestellnummer und demselben Kundennamen in mein System. Huch! Das habe ich davon, wenn ich keinen Schlüssel verwende! Also verwende ich Entity Framework, um eine Zeile zu löschen. Da ich weiß, dass das Duplikat die einzige Bestellung ist, die heute eingegeben wurde, mache ich Folgendes:

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

Wissen Sie was? Ich habe gerade sowohl das Duplikat als auch das Original gelöscht! Das liegt daran, dass ich Entity Framework mitgeteilt habe, dass order_number/cutomer_name mein Primärschlüssel ist. Als ich also sagte, dass duplicateOrder entfernt werden soll, tat es im Hintergrund so etwas wie:

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

Und mit dieser Warnung... sollten Sie nun bereit sein, loszulegen!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X