与Fluent API(现有数据库)的多对多关系
本文关键字:关系 数据库 Fluent API | 更新日期: 2023-09-27 17:53:42
我的应用程序将有用户和组。一个User
可以是多个Group
的一部分。一个Group
也可以有一个以上的User
我一直用这个作为参考。特别是底部标记为"许多关系"的部分。该示例与我的项目之间的区别在于,我的表已经存在,我需要将模型映射到它。我怀疑我应该能够从Membership
表中删除我的主键,它可能会起作用(因为它更接近示例),但我想确保在我弄乱数据库表之前。我的Fluent
也很可能是完全错误的。
编辑
当我进一步研究这个问题的答案时,我偶然发现了一些可以提高答案质量的东西。我要注意的是,需要能够独立添加User
, Usergroup
和Membership
。
CREATE TABLE TestDB.[UserGroup]
(
GroupID int identity not null,
Name varchar(100) not null,
Comment varchar(1000)
PRIMARY KEY(GroupID)
)
CREATE TABLE TestDB.[User]
(
SomeID int not null,
FirstName varchar(100) not null,
LastName varchar(100) not null,
Middle varchar(1) not null,
Email varchar(100) not null,
Phone varchar(16) not null,
Comment varchar(1000)
PRIMARY KEY(SomeID)
)
CREATE TABLE TestDB.[Membership]
(
MembershipID int identity not null,
GroupID int not null,
SomeID int not null
PRIMARY KEY(MembershipID)
FOREIGN KEY(GroupID) references TestDB.[UserGroup](GroupID),
FOREIGN KEY(SomeID) references TestDB.[User](SomeID)
)
注意:SomeID
这样命名是因为它的ID是通过另一个系统给出的。数据库不会自动生成这个特定的ID。它保证是唯一的
public class UserGroup
{
public int GroupID { set; get; }
public string Name { set; get; }
public string Comment { set; get; }
public virtual ICollection<User> Users { set; get; }
}
public class User
{
public string SomeID { set; get; }
public string FirstName { set; get; }
public string LastName { set; get; }
public string Email { set; get; }
public string Phone { set; get; }
public string Comment { set; get; }
public virtual ICollection<UserGroup> UserGroups { set; get; }
}
<<p> 流利的映射/strong> modelBuilder.Entity<User>().ToTable("User", "TestDB");
modelBuilder.Entity<User>().HasKey(r => new { r.SomeID });
modelBuilder.Entity<User>()
.HasMany(r => r.UserGroups)
.WithMany(r => r.Users)
.Map(m =>
{
m.MapLeftKey("SomeID");
m.MapRightKey("GroupID");
m.ToTable("Membership");
});
modelBuilder.Entity<UserGroup>().ToTable("UserGroup", "TestDB");
modelBuilder.Entity<UserGroup>().HasKey(r => new { r.GroupID });
最新一期代码已经更新,以反映我目前所拥有的。我能够独立查询Users
和UserGroups
,但它不允许我访问Navigation Properties
。
我明白了。我最初的问题相当愚蠢,我比我想象的要接近得多。其中一个愚蠢的错误实际上是将两个实体映射到同一个表,这会破坏对该数据库的每次调用。
你需要做的第一件事是确保所有的Navigation properties
都是虚拟的。
public virtual ICollection<User> Users { set; get; }
从这里您需要找出Fluent API映射。我最初忘记包含ToTable
的模式,这使我无法从User
遍历到UserGroup
。在不使用现有数据库的情况下,不需要.Map
块。将自动生成一个包含键SomeID
和GroupID
的表。表名将是两个子表名连接的结果。点击这里阅读更多内容。当使用现有数据库时,这将简单地将它将要创建的表映射到您已经创建的表。
modelBuilder.Entity<User>()
.HasMany(r => r.UserGroups)
.WithMany(r => r.Users)
.Map(m =>
{
m.MapLeftKey("SomeID");
m.MapRightKey("GroupID");
m.ToTable("Membership", "TempDB");
});
另一个伟大的来源
您不需要也不希望在组中有用户,在用户中有组。你应该选择其中之一。恕我直言,我会从UserGroups对象中删除List <user>
。
仍然可以使用Linq查询User
对象的集合,以生成属于特定组的用户列表。