2014-05-09 10 views
15

Ich habe ein Ansichtsmodell, das nur einige der Datenbankmodelleigenschaften einkapselt. Diese vom Ansichtsmodell enthaltenen Eigenschaften sind die einzigen Eigenschaften, die ich aktualisieren möchte. Ich möchte, dass die anderen Eigenschaften ihren Wert erhalten.Entity Framework 6.1 Aktualisierung einer Teilmenge eines Datensatzes

Während meiner Recherchen fand ich this Antwort, die für meine Bedürfnisse jedoch perfekt scheint, trotz meiner besten Bemühungen, kann ich nicht den Code wie erwartet arbeiten. Hier

ist ein isoliertes Beispiel dafür, was ich kam mit:

static void Main() { 
    // Person with ID 1 already exists in database. 

    // 1. Update the Age and Name. 
    Person person = new Person(); 
    person.Id = 1; 
    person.Age = 18; 
    person.Name = "Alex"; 

    // 2. Do not update the NI. I want to preserve that value. 
    // person.NINumber = "123456"; 

    Update(person); 
} 

static void Update(Person updatedPerson) { 
    var context = new PersonContext(); 

    context.Persons.Attach(updatedPerson); 
    var entry = context.Entry(updatedPerson); 

    entry.Property(e => e.Name).IsModified = true; 
    entry.Property(e => e.Age).IsModified = true; 

    // Boom! Throws a validation exception saying that the 
    // NI field is required. 
    context.SaveChanges(); 
} 

public class PersonContext : DbContext { 
    public DbSet<Person> Persons { get; set; } 
} 

public class Person { 
    public int Id { get; set; } 
    [Required] 
    public string Name { get; set; } 
    [Required] 
    public int Age { get; set; } // this is contrived so, yeah. 
    [Required] 
    public string NINumber { get; set; } 
} 

Was mache ich falsch?

+1

Warum Sie die Person angebracht sind, in Frage bereitgestellte Lösung gelöst werden? Wenn ich mit dem Entityframework arbeite, lese ich einfach den Datensatz, ändere seine Eigenschaften und führe SaveChanges() aus; Etwas wie: Person person = context.People.First(); person.Name = "John"; context.SaveChanges(); – Areks

+0

Da dies zwei Abfragen in der Datenbank + in der Realität erfordern würde, verwende ich ein generisches Repository. –

+1

Das ist nicht wirklich ein generisches Repository, aber trotzdem +1 für @Areks. Wenn Sie sich Sorgen um 2 Anfragen machen, dann haben Sie andere Probleme – mituw16

Antwort

4

Sie anhand Ihrer Arbeit auf dem Pfosten https://stackoverflow.com/a/15339512/2015959, aber in dem anderen Thread die Felder, die nicht geändert wurden (und als solche waren in der beigefügten Modell nicht) waren nicht obligatorisch, und das ist, warum es funktionierte . Da Ihre Felder erforderlich sind, erhalten Sie diesen Validierungsfehler.

kann Ihr Problem durch die Entity Framework validation with partial updates

+0

Hey Radu, danke, dass du so genau bist. Du bist der zweite Link ist genau das Problem, das ich hatte. – Jono

0

(Herausgegeben für Klarheit)

Der Kontext muss eine vollständige Kopie des Objekts müssen Geschäftsregeln zu erzwingen. Dies kann nur passieren, wenn das angefügte Objekt alle erforderlichen Eigenschaften enthält oder die Teilansicht vor dem Aktualisieren mit einer vollständigen Kopie zusammengeführt wird.

Ich glaube, dass das, was Sie tun möchten, konzeptionell unmöglich ist: Aktualisierungen wie diese erfordern entweder eine beibehaltene Kopie vor dem Wechsel oder zwei Abfragen an die Datenbank, da die Business-Schicht eine vollständige Kopie des Objekts für die Validierung benötigt.

+0

Könnten Sie bitte eine Quelle zitieren? Ich denke *, dass [diese Antwort] (http://stackoverflow.com/questions/15336248/entity-framework-5-updating-a-record/15339512#15339512) etwas anderes vorschlägt. –

+1

nicht so. Sie können Geschäftsregeln nur für die geänderten Felder erzwingen. Sieh meine Antwort. – jltrem

+0

@ jltrem- Ja, es ist möglich, die Datensatzvalidierung zu deaktivieren, und Sie können die Überprüfung auf Feldebene (erforderlich, Bereich usw.) Eigenschaft für Eigenschaft überprüfen. Diese Methode funktioniert jedoch nicht für ein Objekt mit Regeln auf Datensatzebene (IValidatableObject oder ValidateEntity), bei denen möglicherweise alle Werte der Entität übergeben werden müssen. In jedem Fall erfordert das Umgehen der Business-Layer-Validierung einen Rückgriff auf die Datenbank, um sicherzustellen, dass keine fehlerhaften Daten eingefügt werden. Ich nehme an, mein ursprünglicher Beitrag sollte "konzeptionell unmöglich in einem verantwortungsvollen Design" gesagt haben? – esmoore68

2

Es ist die Validierung, die bewirkt, dass sie nicht gespeichert wird. Sie können die Validierung mit context.Configuration.ValidateOnSaveEnabled = false; deaktivieren und es wird funktionieren. Um bestimmte Felder zu validieren, können Sie var error = entry.Property(e => e.Name).GetValidationErrors(); aufrufen. Sie können also mit Sicherheit eine 'UpdateNameAndAge'-Methode erstellen, die nur Geschäftsregeln erzwingt und diese Eigenschaften als modifiziert markiert. Keine doppelte Abfrage erforderlich.

private static bool UpdateNameAndAge(int id, string name, int age) 
    { 
    bool success = false; 

    var context = new PersonContext(); 
    context.Configuration.ValidateOnSaveEnabled = false; 

    var person = new Person() {Id = id, Name = name, Age = age}; 
    context.Persons.Attach(person); 
    var entry = context.Entry(person); 

    // validate the two fields 
    var errorsName = entry.Property(e => e.Name).GetValidationErrors(); 
    var errorsAge = entry.Property(e => e.Age).GetValidationErrors(); 

    // save if validation was good 
    if (!errorsName.Any() && !errorsAge.Any()) 
    { 
     entry.Property(e => e.Name).IsModified = true; 
     entry.Property(e => e.Age).IsModified = true; 

     if (context.SaveChanges() > 0) 
     { 
      success = true; 
     } 
    } 

    return success; 
    } 
Verwandte Themen