asp.net-mvc-3 - net - how to use entity framework in mvc




Come devo dichiarare le relazioni con le chiavi esterne utilizzando Code First Entity Framework(4.1) in MVC3? (2)

È possibile definire la chiave esterna per:

public class Parent
{
   public int Id { get; set; }
   public virtual ICollection<Child> Childs { get; set; }
}

public class Child
{
   public int Id { get; set; }
   // This will be recognized as FK by NavigationPropertyNameForeignKeyDiscoveryConvention
   public int ParentId { get; set; } 
   public virtual Parent Parent { get; set; }
}

Ora ParentId è una proprietà di chiave esterna e definisce la relazione richiesta tra figlio e genitore esistente. Il salvataggio del bambino senza exsiting genitore genera un'eccezione.

Se il nome della proprietà FK non è costituito dal nome della proprietà di navigazione e dal nome PK principale, è necessario utilizzare l'annotazione dei dati ForeignKeyAttribute o API fluente per mappare la relazione

Annotazione dati:

// The name of related navigation property
[ForeignKey("Parent")]
public int ParentId { get; set; }

API fluente:

modelBuilder.Entity<Child>()
            .HasRequired(c => c.Parent)
            .WithMany(p => p.Childs)
            .HasForeignKey(c => c.ParentId);

Altri tipi di vincoli possono essere applicati mediante annotazioni di dati e convalida del modello .

Modificare:

Otterrai un'eccezione se non imposti ParentId . È richiesta la proprietà (non annullabile). Se non lo si imposta, probabilmente tenterà di inviare il valore predefinito al database. Il valore predefinito è 0, quindi se non hai un cliente con Id = 0 otterrai un'eccezione.

Ho cercato risorse su come dichiarare le relazioni con le chiavi esterne e altri vincoli usando il codice EF 4.1 senza molta fortuna. Fondamentalmente sto costruendo il modello dati nel codice e usando MVC3 per interrogare quel modello. Tutto funziona via MVC che è ottimo (complimenti per Microsoft!) Ma ora voglio che NON funzioni perché ho bisogno di avere vincoli sul modello di dati.

Ad esempio, ho un oggetto Order che ha una tonnellata di proprietà che sono oggetti esterni (tabelle). In questo momento posso creare un Ordine senza problemi, ma senza poter aggiungere la chiave esterna o gli oggetti esterni. MVC3 non risolve questo problema.

Mi rendo conto che potrei semplicemente aggiungere gli oggetti nella classe controller prima di salvare, ma vorrei che la chiamata a DbContext.SaveChanges () fallisse se le relazioni vincolo non fossero state soddisfatte.

NUOVA INFORMAZIONE

Quindi, nello specifico, vorrei che si verificasse un'eccezione quando tento di salvare un oggetto Order senza specificare un oggetto cliente. Questo non sembra essere il comportamento se compongo semplicemente gli oggetti come descritto nella maggior parte della documentazione EF First Code.

Ultimo codice:

public class Order
{
    public int Id { get; set; }

    [ForeignKey( "Parent" )]
    public Patient Patient { get; set; }

    [ForeignKey("CertificationPeriod")]
    public CertificationPeriod CertificationPeriod { get; set; }

    [ForeignKey("Agency")]
    public Agency Agency { get; set; }

    [ForeignKey("Diagnosis")]
    public Diagnosis PrimaryDiagnosis { get; set; }

    [ForeignKey("OrderApprovalStatus")]
    public OrderApprovalStatus ApprovalStatus { get; set; }

    [ForeignKey("User")]
    public User User { get; set; }

    [ForeignKey("User")]
    public User Submitter { get; set; }

    public DateTime ApprovalDate { get; set; }
    public DateTime SubmittedDate { get; set; }
    public Boolean IsDeprecated { get; set; }
}

Questo è l'errore che ottengo ora quando accedo alla vista VS generata per il paziente:

MESSAGGIO DI ERRORE

Il ForeignKeyAttribute sulla proprietà 'Patient' sul tipo 'PhysicianPortal.Models.Order' non è valido. Il nome della chiave esterna "Parent" non è stato trovato nel tipo dipendente "PhysicianPortal.Models.Order". Il valore Nome dovrebbe essere un elenco separato da virgole di nomi di proprietà di chiave esterna.

Saluti,

Guido


Se hai una classe Order , aggiungendo una proprietà che fa riferimento ad un'altra classe nel tuo modello, ad esempio il Customer dovrebbe essere sufficiente per far sapere a EF che c'è una relazione lì dentro:

public class Order
{
    public int ID { get; set; }

    // Some other properties

    // Foreign key to customer
    public virtual Customer Customer { get; set; }
}

È sempre possibile impostare la relazione FK esplicito:

public class Order
{
    public int ID { get; set; }

    // Some other properties

    // Foreign key to customer
    [ForeignKey("Customer")]
    public string CustomerID { get; set; }
    public virtual Customer Customer { get; set; }
}

Il costruttore ForeignKeyAttribute accetta una stringa come parametro: se la si posiziona su una proprietà di chiave esterna rappresenta il nome della proprietà di navigazione associata. Se lo si posiziona sulla proprietà di navigazione, rappresenta il nome della chiave esterna associata.

Ciò significa che, se si posiziona il ForeignKeyAttribute sulla proprietà Customer , l'attributo prende CustomerID nel costruttore:

public string CustomerID { get; set; }
[ForeignKey("CustomerID")]
public virtual Customer Customer { get; set; }

MODIFICA basata sul codice più recente Si ottiene questo errore a causa di questa riga:

[ForeignKey("Parent")]
public Patient Patient { get; set; }

EF cercherà una proprietà denominata Parent per usarla come chiave di sicurezza per le chiavi esterne. Puoi fare 2 cose:

1) Rimuovi ForeignKeyAttribute e sostituiscilo con RequiredAttribute per contrassegnare la relazione come richiesto:

[Required]
public virtual Patient Patient { get; set; }

Anche la decorazione di una proprietà con RequiredAttribute ha un effetto collaterale: la relazione nel database viene creata con ON DELETE CASCADE .

Vorrei anche raccomandare di rendere la proprietà virtual per abilitare il caricamento lento.

2) Creare una proprietà denominata Parent che fungerà da Chiave esterna. In tal caso, probabilmente ha più senso chiamarlo per esempio ParentID (dovrai anche cambiare il nome in ForeignKeyAttribute ):

public int ParentID { get; set; }

Nella mia esperienza in questo caso, però, funziona meglio per avere il contrario:

[ForeignKey("Patient")]
public int ParentID { get; set; }

public virtual Patient Patient { get; set; }






entity-framework-4.1