实体框架 - 模型化多对多关系

时间:2015-12-09 16:24:58

标签: entity-framework

我正试图在Entity Framework 6 Code-First中建立二级多对多关系(一个多对多对多的关系)。

我有两个名为PreferencesSubPreferences的引用类,即每个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中建模这种类型的关系,还是需要构建正式的对象/类来定义关系?

我应该提一下,我无法更改现有的表结构,因为它们也被套件中的旧应用程序使用。

1 个答案:

答案 0 :(得分:1)

嗯,这是我的意见:

PreferenceSubPreference实际上是一回事。因此,只有使用自我关系的模型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");
    });

现在,UserPreference相关,Preference可能是“subPreference”。

我相信它可以解决你的问题。