6

vedo un sacco di esempi sull'uso di codice EF prima con pocos che mostrano qualcosa di simile:Devo tenere le chiavi esterne in sincronia con i riferimenti quando si utilizza pocos

public class Post 
{ 
    public int PostId { get; set; } 
    public string Title { get; set; } 
    public string Content { get; set; } 

    public int BlogId { get; set; } 
    public virtual Blog Blog { get; set; } 
} 

Ora, guardate la proprietà Blog. Non dovrebbe essere così, invece:

private Blog blog; 
public virtual Blog Blog 
{ 
    get 
    { 
     return blog; 
    } 
    set 
    { 
     blog = value; 
     if (blog != null) 
     { 
      BlogId = blog.BlogId; 
     } 
    } 
} 

Voglio dire, dal momento che già sta "inquinare" il modello con la chiave esterna, non dovresti almeno mantenerlo sincronizzato con il riferimento? Oppure non dovresti fare affidamento su BlogId durante la lettura dei dati (ad esempio, come se volessi sapere se uno specifico BlogId è in un elenco). O forse c'è una proprietà magica su DbContext (come KeepForeingKeysPropertiesSyncronizedWithReferences) che lo fa a me e io sono l'unico programmatore triste che si preoccupa di questo? O sono paranoico? (Anche, mi dispiace per il mio povero inglese)

EDIT spiacenti per questo - è stato davvero una domanda stupida. Stefan ha ragione, EF lo fa davvero per te. Non ho visto questo perché i riferimenti che stavo passando sono stati caricati con AsNoTracking(). Solo in questa condizione avremo un riferimento con ID e il campo chiave esterna sarà 0. Finché si passa un riferimento già presente nel contesto, dovrebbe funzionare.

+1

non conoscono EF, ma aveva si è utilizzato NHibernate che non mettereste nella proprietà BlogId a tutti. – erikkallen

+0

Penso che avere la possibilità di usare il BlogId sia bello, quindi non ho bisogno di avere un riferimento sul blog e comunque posso salvare l'associazione. Sono solo confuso su come mantenerlo sincronizzato - per me sembra la cosa più ovvia da fare ma non ho mai visto qualcuno farlo, quindi forse ho sbagliato: / – user1526627

risposta

1

Non è necessario farlo di per sé, EF lo fa per te.
Se si imposta la proprietà di associazione indipendente, EF sincronizzerà la proprietà della chiave esterna per riflettere la modifica e viceversa. Non succede immediatamente automaticamente, penso che questo accada dopo aver chiamato SaveChanges ma non ne sono sicuro.
Se vuoi sapere perché alcune persone usano la proprietà della chiave esterna: è più conveniente in app distaccate come le app web. Quando devi ridimensionare la tua app, può anche aiutarti a migliorare le prestazioni (leggi questo in un recente post sul blog di MS).
Fondamentalmente, devi solo farlo da solo se stai mescolando e facendo corrispondenze; quando in un metodo stai usando la proprietà di associazione indipendente e in un altro stai usando la proprietà della chiave esterna.

0

Database Primo codice generato.

Sembra che si si altrimenti riceverai il seguente errore.

una violazione di vincoli di integrità referenziale verificato: La proprietà valori che definiscono i vincoli di riferimento non sono coerenti tra capitale e oggetti dipendenti nel rapporto.

Il principio è l'oggetto Post, dipendente dall'oggetto Blog.

quando si tenta di collegare il contesto non allocato libero POCO torna al contesto EF 4.1 DbContext:

using (TransactionScope scope = new TransactionScope()) 
using (ITAMdbContext db = new ITAMdbContext()) 
{ 
    db.Entry(post).State = System.Data.EntityState.Unchanged; // error here 
    db.Entry(post).State = System.Data.EntityState.Modified; 
    db.SaveChnages(); 

Questo errore si risolve ..

using (TransactionScope scope = new TransactionScope()) 
using (ITAMdbContext db = new ITAMdbContext()) 
{ 
    post.BlogId = post.Blog.BlogId; 
// fix the broken FK value, EF will not do this for 
// you, it does not know if post.BlogId or the post.Blog.BlogId should be chosen. 

    db.Entry(post).State = System.Data.EntityState.Unchanged; 
    db.Entry(post).State = System.Data.EntityState.Modified; 
    db.SaveChnages(); 

farlo a modo tuo è valida se i tuoi oggetti POCO non vengono generati automaticamente.

il motivo per cui si imposta post su Unchanged, quindi impostarlo su Modified è perché il primo Entry().Lo stato impostato su un oggetto converte lo stesso stato in tutti gli oggetti figlio! orribile, ma è così che sembra funzionare. quindi, quando lo chiami di nuovo, modifica solo l'oggetto post. In questo modo gli oggetti figlio vengono modificati o aggiunti.

EDIT: Questo non è più necessario, il suo fatto per voi

Problemi correlati