Sono nuovo in Entity Framework quindi non ne so molto. Attualmente sto lavorando su My College Project, in quel progetto mi sono imbattuto in un problema in cui ho due chiavi esterne si riferisce alla stessa colonna in un altro tavolo. come posso gestire questa situazione.
È necessario creare proprietà di navigazione per ogni chiave esterna. E se creo un'altra proprietà Navigaton per ContactId, è necessario creare un'altra proprietà di navigazione nella classe User come:
public virtual ICollection<BlockedUser> SomePropertyName { get; set; }
per favore dimmi il modo migliore per superare questo problema. Sto usando Entity Framework 6.
Ecco le mie classi di modelli:
public class BlockedUser
{
// User Foreign Key
public int UserId { get; set; } // Composite Primary Key
// User Foreign key
public int ContactId { get; set; } // Composite Primary Key
// User Navigation Property
public virtual User User { get; set; }
}
public class User
{
public int UserId { get; set; } // Primary key
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
// BlockedUser Navigation Property
public virtual ICollection<BlockedUser> BlockedUsers { get; set; }
}
È necessario creare proprietà di navigazione per ogni chiave esterna?
Sì, o più precisamente: hai bisogno di almeno una proprietà di navigazione per ogni relazione . "Almeno uno" significa che puoi decidere su quale delle due entità vuoi aggiungere la proprietà di navigazione. Normalmente dipende dai casi d'uso più comuni nella tua applicazione se desideri spesso navigare dall'entità A all'entità B o viceversa. Se lo desideri, puoi aggiungere le proprietà di navigazione a entrambe le entità ma non è necessario.
Nel tuo modello apparentemente hai due relazioni (uno-a-molti). Se desideri esporre le proprietà di navigazione in entrambe le entità, avrai bisogno di quattro proprietà di navigazione e - importante! - devi definire quali proprietà di navigazione formano una coppia per una relazione (vedi l'attributo [InverseProperty]
nel seguente snippet di codice).
Con le annotazioni di dati vorrebbe questo:
public class BlockedUser
{
[Key, ForeignKey("User"), Column(Order = 1)]
public int UserId { get; set; }
[Key, ForeignKey("Contact"), Column(Order = 2)]
public int ContactId { get; set; }
[InverseProperty("BlockedUsers")]
public virtual User User { get; set; }
[InverseProperty("BlockedContacts")]
public virtual User Contact { get; set; }
}
public class User
{
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public virtual ICollection<BlockedUser> BlockedUsers { get; set; }
public virtual ICollection<BlockedUser> BlockedContacts { get; set; }
}
Se non vuoi la raccolta BlockedContacts
, puoi probabilmente rimuoverla e anche l' [InverseProperty("BlockedContacts")]
dalla proprietà di navigazione Contact
.
È possibile utilizzare l'attributo ForeignKey per risolvere il problema. ForeignKey viene utilizzato per associare la proprietà di navigazione e la proprietà della chiave esterna. Non vi è alcuna differenza tra l'annotazione dei dati FK con la proprietà Chiave esterna e FK con le Proprietà di navigazione. Tuttavia, il codice seguente creerà due chiavi esterne con un nome diverso.
public class BlockedUser
{
// User Foreign Key
[ForeignKey("UserId")]
public int UserId { get; set; } // Composite Primary Key
// User Foreign key
[ForeignKey("BlockedUser_User")]
public int ContactId { get; set; } // Composite Primary Key
// User Navigation Property
public virtual User User { get; set; }
}
public class User
{
public int UserId { get; set; } // Primary key
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
// BlockedUser Navigation Property
public virtual ICollection<BlockedUser> BlockedUsers { get; set; }
}