2017-08-07 26 views
0

我使用.NET Core最終實體框架核心在兩個實體之間建立多對多關係。我已經建立了連接實體滿足要關係,基於陰影屬性的主鍵是這樣的:以多對多關係作爲影子屬性的複合主鍵

實體用戶:

public class User 
{ 
    [Key] 
    public int IDUser { get; set; } 
    [Required] 
    public string Forename { get; set; } 

    public List<UserGroup> UsersGroups { get; set; } 
} 

實體組:

public class Group 
{ 
    [Key] 
    public int IDGroup { get; set; } 
    [Required] 
    public string GroupName { get; set; } 

    public List<UserGroup> UsersGroups { get; set; } 
} 

實體用戶組:

public class UserGroup 
{ 
    public Group Group { get; set; } 
    public User User { get; set; } 
} 

DB上下文類別:

public class DBContext : DbContext 
{ 
    public DBContext(DbContextOptions<DBContext> options) 
     : base(options) 
    { 

    } 


    protected override void OnModelCreating(ModelBuilder modelBuilder) 
    { 
     // shadow property - primary/foreign key 
     modelBuilder.Entity<UserGroup>() 
      .Property<int>("IDUser"); 

     // shadow property - primary/foreign key 
     modelBuilder.Entity<UserGroup>() 
      .Property<int>("IDGroup"); 

     // composite primary key based on shadow properties 
     modelBuilder.Entity<UserGroup>() 
      .HasKey(new string[]{ "IDUser", "IDGroup" }); 

     modelBuilder.Entity<UserGroup>() 
      .HasOne(ug => ug.Group) 
      .WithMany(g => g.UsersGroups) 
      .HasForeignKey(???); //what to do here ? 

     modelBuilder.Entity<UserGroup>() 
      .HasOne(ug => ug.User) 
      .WithMany(u => u.UsersGroups) 
      .HasForeignKey(???); // what to do here ? 

     base.OnModelCreating(modelBuilder); 
    } 

    public DbSet<Group> Groups { get; set; } 
    public DbSet<User> Users { get; set; } 
    public DbSet<UserGroup> UserGroups { get; set; } 
} 

現在。我如何根據我的影子組合主鍵在UserGroup實體上正確建立外鍵?我希望這個陰影主鍵同時是外鍵。我現在不知道如何引用這個陰影主鍵來創建外鍵。我標記了我不知道如何處理問號。

+1

不知道你的意思是使複合PK爲FK。 FK是指向* principal *(引用)表的PK的屬性(陰影或不)。在你的情況下,你應該分別使用''IDGroup「'和''IDUser」'代替''''。 –

+0

https://docs.microsoft.com/en-us/ef/core/modeling/relationships 本文的最後一節(多對多)。存在具有顯式外鍵(PostId,TagID)的連接實體'PostTag',它們是同時是主鍵(在'OnMOdelCreating'方法中的流暢API中建立的)。我只想得到與陰影屬性相同的效果。 –

+0

它們只是用流利的API建立的複合PK的**部分**。您已經定義了具有陰影屬性的複合PK,因此您現在只需將該鍵的各個部分映射爲FK。你是否嘗試了我在之前的評論結尾處寫的內容? –

回答

1

你要創建一個多一對多連接表沒有定義任何標量的屬性和您正在使用陰影屬性來配置連接表。對於EF流利的API,你必須引用一個影子屬性,你需要使用基於字符串的方法。由於缺乏支持,CLR屬性lambda表達式不起作用。

就你而言,「在這裏做什麼」部分就是使用屬性的字符串名稱。 例如

modelBuilder.Entity<UserGroup>() 
    .HasOne(ug => ug.Group) 
    .WithMany(g => g.UsersGroups) 
    .HasForeignKey("IDGroup"); //what to do here ? 

相同的其他關係。當您想要將陰影屬性配置爲您的外鍵屬性時,這是一般機制。此外,在HasForeignKey中配置shadow屬性並不要求您事先定義shadow屬性,因爲EF可以根據關係主體側的屬性來推斷該類型。雖然對於HasKey,您仍然需要聲明陰影屬性,因爲EF不知道類型。 (正如你在你的例子中所做的那樣)

EF Core也有約定FK屬性。其中一個慣例是使用財產作爲FK,如果它與主要財產具有相同的名稱。在上述特例中,由於您的主方主鍵屬性被命名爲IDGroup,它與您嘗試配置的外鍵相同,所以EF將按照慣例自動使用該鍵。這意味着你可以忽略配置你的關係(就像@David建議的那樣)。此外,由於EF根據導航發現關係,您可以從應用程序中完全刪除以下代碼片段,並創建相同的模型。

modelBuilder.Entity<UserGroup>() 
    .HasOne(ug => ug.Group) 
    .WithMany(g => g.UsersGroups); 
//.HasForeignKey(???); //what to do here ? 

modelBuilder.Entity<UserGroup>() 
    .HasOne(ug => ug.User) 
    .WithMany(u => u.UsersGroups); 
    //.HasForeignKey(???); // what to do here ? 
1

.HasForeignKey()聲明實體上的外鍵屬性。

如果您不希望鏈接實體上的外鍵屬性(並且您應該擁有它們),只需省略.HasForeignKey聲明,EF將按照慣例使用映射FK列。

例如

保護覆蓋無效OnModelCreating(模型構建模型構建器) { //陰影屬性 - 主鍵/外鍵 modelBuilder.Entity() .Property( 「ID用戶所」);

// shadow property - primary/foreign key 
    modelBuilder.Entity<UserGroup>() 
     .Property<int>("IDGroup"); 

    // composite primary key based on shadow properties 
    modelBuilder.Entity<UserGroup>() 
     .HasKey(new string[] { "IDUser", "IDGroup" }); 

    modelBuilder.Entity<UserGroup>() 
     .HasOne(ug => ug.Group) 
     .WithMany(g => g.UsersGroups); 
    //.HasForeignKey(???); //what to do here ? 

    modelBuilder.Entity<UserGroup>() 
     .HasOne(ug => ug.User) 
     .WithMany(u => u.UsersGroups); 
     //.HasForeignKey(???); // what to do here ? 

    base.OnModelCreating(modelBuilder); 
} 

生成

CREATE TABLE [UserGroups] (
    [IDUser] int NOT NULL, 
    [IDGroup] int NOT NULL, 
    CONSTRAINT [PK_UserGroups] PRIMARY KEY ([IDUser], [IDGroup]), 
    CONSTRAINT [FK_UserGroups_Groups_IDGroup] FOREIGN KEY ([IDGroup]) REFERENCES [Groups] ([IDGroup]) ON DELETE CASCADE, 
    CONSTRAINT [FK_UserGroups_Users_IDUser] FOREIGN KEY ([IDUser]) REFERENCES [Users] ([IDUser]) ON DELETE CASCADE 
); 
相關問題