我正试图在Entity Framework 6 Code-First
中建立二级多对多关系(一个多对多对多的关系)。
我有两个名为Preferences
和SubPreferences
的引用类,即每个Preference
将定义一个或多个Sub-Preferences
。
public class Preference
{
[Key]
public int Id { get; set; }
public string Name get; set; }
// Navigation
public virtual ICollection<SubPreference> SubPrefeences { get; set; }
}
public class SubPreference
{
[Key]
public int Id { get; set; }
public int PreferenceId { get; set; }
public string Name get; set; }
// Navigation
public virtual Preference Prefeences { get; set; }
}
我还有一个User
课程。每个User
都可以选择/分配一个或多个Preferences
:
public class User
{
[Key]
public int Id { get; set; }
public string Email { get; set; }
// Navigation
public virtual ICollection<Preferences> Preferences { get; set; }
}
在数据上下文中,它映射如下:
public class UserMap
: EntityTypeConfiguration<User>
{
public UserMap()
{
ToTable("Users");
// Primary Key
HasKey(t => t.Id);
Property(u => u.Id).IsRequired().HasColumnName("Id");
Property(u => u.Email).IsRequired().HasMaxLength(256).HasColumnName("Email");
HasMany(u => u.Preferences)
.WithMany()
.Map(x =>
{
x.MapLeftKey("UserId");
x.MapRightKey("PreferenceId");
x.ToTable("UserPreferences");
});
}
}
这使用以下多对多SQL链接表:
CREATE TABLE [dbo].[UserPreferences] (
[UserId] INT NOT NULL,
[PreferenceId] INT NOT NULL,
CONSTRAINT [PK_dbo.UserPreferences]
PRIMARY KEY CLUSTERED ([UserId] ASC, [PreferenceId] ASC),
CONSTRAINT [FK_dbo.UserPreferences_dbo.Users_Id]
FOREIGN KEY ([UserId])
REFERENCES [dbo].[Users] ([Id])
ON DELETE CASCADE
CONSTRAINT [FK_dbo.UserPreferences_dbo.Preferences_Id]
FOREIGN KEY ([PreferenceId])
REFERENCES [dbo].[Preferences] ([Id])
ON DELETE CASCADE,
);
User
然后可以通过在用户界面(UI)上选择一个或多个Preference
复选框来管理其首选项。所有这些都按预期工作。
此要求现已更改,因此User
不仅可以选择其“偏好设置”,还可以按Preferences
优化SubPreference
。从用户界面的角度来看,用户会检查Preference
,然后会为所选SubPreferences
的{{1}}显示一个复选框列表。
实际上,这会创建一个多对多关系。是否可以通过扩展上面的代码在Entity Framework中建模这种类型的关系,还是需要构建正式的对象/类来定义关系?
我应该提一下,我无法更改现有的表结构,因为它们也被套件中的旧应用程序使用。
答案 0 :(得分:1)
嗯,这是我的意见:
Preference
和SubPreference
实际上是一回事。因此,只有使用自我关系的模型Preference
才足够。 Preference
可能有很多Preference
,也可能有“父”Preference
。像这样:
public class Preference
{
public int Id { get; set; }
public string Name get; set; }
public int? ParentId { get; set; }
public Preference Parent { get; set; }
// Navigation
public virtual ICollection<Preference> SubPreferences { get; set; }
}
然后,User
映射将是这样的:
modelBuilder.Entity<Preference>()
.HasOptional(i => i.ParentPreference)
.WithMany(i => i.SubPreferences)
.HasForeignKey(i => i.ParentId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<User>()
.HasMany(u => u.Preferences)
.WithMany()
.Map(x =>
{
x.MapLeftKey("UserId");
x.MapRightKey("PreferenceId");
x.ToTable("UserPreferences");
});
现在,User
与Preference
相关,Preference
可能是“subPreference”。
我相信它可以解决你的问题。