[英]Entity Framework core one to many relationship
我正在嘗試建立具有一對多關系的代碼優先數據模型。
有一個UserDTO和RoleDTO模型,其中User包含一對多角色。
RoleDTO的一些簡化代碼是:
internal class RoleDTO
{
public UserDTO User { get; set; }
public string Value { get; set; }
public RoleDTO()
{
}
}
和簡化的UserDTO:
internal class UserDTO
{
public string Email { get; set; }
public string FullName { get; set; }
public string UserName { get; set; }
public virtual ICollection<RoleDTO> Roles { get; set; }
public UserDTO()
{
}
}
最后是從DBContext繼承的類
class StorageContext : DbContext
{
public DbSet<UserDTO> Users { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"My_Connection_String");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserDTO>().HasKey(entity => entity.Email);
modelBuilder.Entity<UserDTO>().HasMany(entity => entity.Roles);
modelBuilder.Entity<RoleDTO>().HasOne<UserDTO>().WithMany(x => x.Roles);
modelBuilder.Entity<RoleDTO>().HasKey(x => x.Value);
}
}
當我運行添加遷移時,我沒有數據庫或遷移文件夾(即使我仍然在擁有一些列之后運行了該文件夾),Role表也會用指向用戶電子郵件地址的額外列創建。
我只希望角色表中有兩列,一列是用戶的電子郵件地址,是用戶電子郵件PK的FK,另一列是與外鍵組合的字符串值,在用戶表中構成復合主鍵。 下圖:
******************************* * Role * ******************************* * User_Email - string/varchar * * Value - string /varchar * ******************************* FK - User_Email to User table Email column PK - User_Email, Value compound primary key
有誰知道如何使用流暢的API或數據注釋來實現這一目標?
謝謝!
我不確定您要達到的目的,但是在ORM中使用復合鍵可能會很復雜,而且可能是不可預測的。 因此,除非您有充分的理由,否則我建議您不要使用復合鍵。
我建議不要在任何地方將電子郵件地址用作PK。 使用唯一生成的Int32 / Int64甚至Guid作為主鍵(一旦設置了關系,它將作為外鍵反映在您的Roles表中),並在您的電子郵件列(在User表中)上添加一個索引,唯一的約束。 您可以在遷移腳本中添加索引。 至少以這種方式,如果電子郵件地址要更改(如果要更改),則可以保留身份。
我希望這有幫助。
首先,類UserDTO
沒有名為User_Email
屬性。 您可以使用EF在模型中定義陰影屬性,但考慮到您希望它在模型中,則應在類public string User_Email
上定義屬性
使用流利的API在類上定義上述屬性或在模型中定義陰影屬性后,
要定義復合主鍵,您需要使用HasKey
流利的API。 您不能使用數據注釋來定義復合主鍵。
要將User_Email, Value
定義為復合PK,請在OnModelCreating
編寫以下代碼(如果定義了陰影屬性,則可以這樣做)
modelBuilder.Entity<UserDTO>().HasKey(e => new { e.User_Email, e.Value });
要為關系指定外鍵屬性,可以在fk屬性/導航上使用ForeignKeyAttribute
,也可以使用HasForeignKey
fluent API。
要設置User_Email
是FK到UserDTO
表,假設UserDTO User
在RoleDTO
& ICollection<RoleDTO> Roles
在UserDTO
是這種關系導航。
使用數據注釋,在User_Email
屬性上寫ForeignKey("User")
或在任一導航( User
/ Roles
)上寫ForeignKey("User_Email")
)。 請記住,如果您具有User_Email
作為shadow屬性,則不能使用它。
使用Fluent API,在OnModelCreating
編寫以下代碼以完全配置關系
modelBuilder.Entity<RoleDTO>().HasOne(e => e.User).WithMany(e => e.Roles).HasForeignKey(e => e.User_Email);
上面將使用“ User
和Roles
導航創建一對多關系,該導航使用User_Email
作為外鍵屬性。
您的代碼無法正常工作的原因是
HasKey
,您定義了單個屬性PK而不是復合PK。 HasForeignKey
方法指定外鍵屬性,因此EF將為您添加陰影屬性。 此外,在關系配置中,您僅使用了Roles
導航。 EF將嘗試使用“ User
導航”創建另一個關系,從而在UserDTO
和RoleDTO
之間有效地建立2個關系。 這就是您獲得額外的列的原因,因為EF按照慣例創建了陰影屬性以用作外鍵屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.