Sto costruendo un'applicazione usando prima il codice EF 6.1. Il modello di entità contiene le seguenti classi:
public enum UnitSystem {
English,
Metric
}
public enum UnitTypes {
Volume,
Weight,
Other
}
public class Unit {
[DatabaseGenerated( DatabaseGeneratedOption.Identity ), Key]
public int UnitId { get; set; }
[Required, MaxLength( 128 ), Index( IsUnique = true )]
public string UnitName { get; set; }
[Required]
public UnitSystem UnitSystem { get; set; }
[Required]
public UnitTypes UnitType { get; set; }
public virtual ICollection<Item> Items { get; set; }
}
public class Item {
[DatabaseGenerated( DatabaseGeneratedOption.Identity ), Key]
public int ItemId { get; set; }
[Required, MaxLength( 128 ), Index( IsUnique = true )]
public string ItemName { get; set;
[Required]
public int UnitId { get; set; }
[ForeignKey( "UnitId" )]
public virtual Unit Units { get; set; }
/// Other unimportant properties
}
public class UnitConversion {
[Required, Key, Column( Order = 0 )]
public int FromUnitId { get; set; }
[ForeignKey( "FromUnitId" )]
public virtual Unit FromUnit { get; set; }
[Required, Key, Column( Order = 1)]
public int ToUnitId { get; set; }
[ForeignKey( "ToUnitId" )]
public virtual Unit ToUnit { get; set; }
[Key, Column( Order = 2 )]
public int? ItemId { get; set; }
public virtual Item Item { get; set; }
[Required]
public double ConversionFactor { get; set; }
}
Quando EF crea il database, viene visualizzato il messaggio "Introduci il messaggio ESTERO CHIAVE IN COSTRUZIONE". Ho bisogno che la proprietà ItemId
sia annullabile e, se non è nulla, ho bisogno che sia una chiave esterna nella tabella degli Items
.
Qual è il modo giusto per creare questa relazione per evitare l'errore di eliminazione a cascata?
modificare
Non ricevo più l'errore nella colonna ItemId
; ora sto ricevendo per le colonne FromUnitId
o ToUnitId
, o entrambi.
Ho aggiunto proprietà di navigazione alla classe Unit
:
[ForeignKey("FromUnitId")]
public virtual ICollection<UnitConversion> FromConversions { get; set; }
[ForeignKey("ToUnitId")]
public virtual ICollection<UnitConversion> ToConversions { get; set; }
E questo è il testo completo del messaggio di errore che ottengo:
L'introduzione del vincolo FOREIGN KEY "FK_dbo.UnitConversions_dbo.Units_ToUnitId" nella tabella "UnitConversions" può causare cicli o più percorsi a cascata. Specificare ON DELETE NO ACTION o ON UPDATE NO ACTION o modificare altri vincoli FOREIGN KEY.
Si suppone che ci sia una relazione zero-or-one per molte tra la tabella UnitConversions
e la tabella Units
. Quando provo a creare la chiamata a modelBuiloder.Entity<UnitConversions>().WillCascadeOnDelete(false)
, IntelliSense non mostra il metodo WillCascadeOnDelete
e il codice non verrà compilato.
Per prima cosa ti consiglio di fare una rapida lettura di entityframeworktutorial per assicurarti di avere le tue chiavi configurate come suggerito. Per un rapporto 1 a 1 è un po 'complicato; fondamentalmente la chiave primaria del "Bambino" è una chiave estranea al "Genitore".
In alternativa puoi usare l'API fluente nel contesto dati e fare qualcosa di simile per assicurarti che la relazione e la cascata vadano come previsto:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Student>().HasOptional(e => e.StudentAddress)
.WithRequired(m => m.Student);
modelBuilder.Entity<StudentAddress>.WillCascadeOnDelete(false);
}
Questo dice che uno studente ha uno StudentAddress opzionale, e lo StudentAddress ha uno Studente richiesto, e quando lo StudentAddress è cancellato lo Studente non lo è.