我正在使用.NET Core end Entity Framework核心来构建两个实体之间的多对多关系。我已经建立了连接实体来完全填充关系和基于阴影属性的主键,如下所示:
实体用户:
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; }
}
DBcontext类:
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实体上正确建立外键?我希望这个影子主键同时是外键。我现在不知道如何引用这个影子主键来制作外键。我标记了我不知道如何处理问号。
答案 0 :(得分:2)
.HasForeignKey()在您的实体上声明外键属性。
如果您不想在链接实体上使用外键属性(并且您应该拥有它们),只需省略.HasForeignKey声明,EF将按惯例使用映射FK列。
例如
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);
}
生成
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
);
答案 1 :(得分:2)
您正在尝试创建多对多连接表而不定义任何标量属性,并且您正在使用shadow属性来配置连接表。对于EF fluent API,您必须引用shadow属性,您需要使用基于字符串的方法。由于缺乏支持CLR属性,lambda表达式不起作用。
在你的情况下,&#34;在这里做什么&#34; part只是使用属性的字符串名称。 e.g。
modelBuilder.Entity<UserGroup>()
.HasOne(ug => ug.Group)
.WithMany(g => g.UsersGroups)
.HasForeignKey("IDGroup"); //what to do here ?
其他关系相同。当您要将shadow属性配置为外键属性时,这是一般机制。此外,在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 ?