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...

0voto

Arno Tolmeijer Punkte 41

Ich fand die ursprüngliche Antwort, die .edmx-Datei zu aktualisieren, in meiner Situation am besten. Ich war nur nicht allzu glücklich darüber, das Modell jedes Mal zu ändern, wenn es in der Datenbank aktualisiert wurde. Deshalb habe ich eine zusätzliche Textvorlagendatei geschrieben, die automatisch aufgerufen wird, wenn sich das Modell geändert hat - genauso wie die Entitäten neu erzeugt werden. Ich poste sie hier in diesem Kommentar. Damit es funktioniert, müssen Sie die Datei wie {Modellname}.irgendwas.tt benennen und sie im gleichen Ordner wie Ihren .edmx-Ordner speichern. Ich habe es {Modellname}.NonPkTables.tt genannt. Aufgrund der ungültigen Dateierweiterungsdefinition in der zweiten Zeile wird keine eigenständige Datei erzeugt. Sie können sie gerne verwenden.

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ output extension="/" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq"#>
<#@ assembly name="%VS120COMNTOOLS%..\IDE\EntityFramework.dll" #>
<#@ assembly name="%VS120COMNTOOLS%..\IDE\Microsoft.Data.Entity.Design.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Windows.Forms" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Xml.Linq" #>
<#@ import namespace="System.Globalization" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Data.Entity.Core.Metadata.Edm" #>
<#@ import namespace="System.Data.Entity.Core.Mapping" #>
<#@ import namespace="System.CodeDom" #>
<#@ import namespace="System.CodeDom.Compiler" #>
<#@ import namespace="Microsoft.CSharp"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="System.Diagnostics" #>

<#
    string modelFileName= this.Host.TemplateFile.Split('.')[0] + ".edmx";
    string edmxPath = this.Host.ResolvePath( modelFileName );

    // MessageBox.Show( this.Host.TemplateFile + " applied." );
    var modelDoc = XDocument.Load(edmxPath);
    var root = modelDoc.Root;
    XNamespace nsEdmx = @"http://schemas.microsoft.com/ado/2009/11/edmx";
    XNamespace ns = @"http://schemas.microsoft.com/ado/2009/11/edm/ssdl";

    var runtime = root.Elements(nsEdmx + "Runtime").First();
    var storageModels = runtime.Elements(nsEdmx + "StorageModels").First();
    XNamespace nsStore = @"http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator";

    var schema = storageModels.Elements(ns + "Schema").First();
    XNamespace nsCustomAnnotation = @"http://schemas.microsoft.com/ado/2013/11/edm/customannotation";

    var entityTypes = schema.Nodes().OfType<XComment>().Where(c => c.Value.Contains("warning 6002: The table/view"));
    bool changed = false;

    foreach (var node in entityTypes)
    {
        var element = node.ElementsAfterSelf().First();
        string entityName = element.Attribute("Name").Value;

        // Find EntitySet in EntityContainer.
        var entityContainer = schema.Elements(ns + "EntityContainer").First();
        var entitySet = entityContainer.Elements(ns + "EntitySet").First(s => s.Attribute("Name").Value == entityName);

        // Change "store:Schema" attribute to "Schema" attribute.
        var attribute = entitySet.Attribute(nsStore + "Schema");

        if (attribute != null)
        {
            string schemaName = entitySet.Attribute(nsStore + "Schema").Value;
            entitySet.Attribute(nsStore + "Schema").Remove();
            entitySet.Add(new XAttribute("Schema", schemaName));
            changed |= true;
        }

        // Remove the DefiningQuery element.
        var definingQuery = entitySet.Element(ns + "DefiningQuery");

        if (definingQuery != null)
        {
            definingQuery.Remove();
            changed |= true;        
            Debug.WriteLine(string.Format("Removed defining query of EntitySet {0}.", entityName));
        }
    }

    if (changed)
        modelDoc.Save(edmxPath);
#>

0voto

Brian Punkte 3583

Ich habe das Problem behoben, indem ich das EF-Projekt und alle seine Klassen einfach gelöscht und neu erstellt habe. Siehe Details unten:

Ich habe mich eine Stunde lang mit diesem Problem herumgeschlagen, dann das EF-Projekt mit dem Fehler gelöscht, meinen gesamten benutzerdefinierten Code gespeichert und das Ganze dann neu erstellt. Da es nur darum ging, ein neues EF-Diagramm und dessen inneren Code zu erstellen, dauerte die Behebung des Problems etwa 10 Minuten.

Ich vermute, dass das Problem darin besteht, dass die Datenbank-First-Methode zur Generierung von EF-Klassen und -Eigenschaften nach zwei oder drei "Aktualisierungen" ein wenig seltsam wird. Im Grunde habe ich ein Problem im Code-Verhalten gefunden, die Eigenschaften der Datenbanktabelle korrigiert und dann das EF-Diagramm einmal zu oft aktualisiert. Dann habe ich versucht, am Code herumzufummeln, was nicht funktionierte.

Der Neuanfang hat funktioniert.

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