多对多并且在EF中级联而没有反向属性

时间:2013-06-17 23:20:15

标签: entity-framework ef-code-first mapping many-to-many entity-framework-5

我的域模型User中有一个对象,其中包含配置设置列表。它看起来像这样:

public class User
{
    public int ID { get; set; }

    /* various user properties */

    public List<ConfigurationSetting> Settings { get; set; }
}

配置设置具有以下定义:

public class ConfigurationSetting
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
    public MasterAccount Account { get; set; }
}

如您所见,配置类中没有反向导航属性。这是因为设置附加到MasterAccount并可选地应用于User,因此需要映射表。

我正在尝试在配置UserConfiguration中创建关系,如下所示:

            HasMany(x => x.Settings)
            .WithMany()
            .Map(m =>
            {
                m.ToTable("MapUserSettings");
                m.MapLeftKey("UserId");
                m.MapRightKey("SettingId");
            });

请注意,使用以下内容重命名ID:

        HasKey(x => x.ID);
        Property(x => x.ID)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
            .HasColumnName("UserId");

当EF Code First尝试创建模型时,我得到以下内容:

'FK_dbo.MapUserSettings_dbo.Settings_SettingId' on table 'MapUserSettings' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

如何正确配置级联?

1 个答案:

答案 0 :(得分:2)

考虑到你提供的信息,我试图重现你的问题,我不能让EF抱怨建立模型。

你没有提供的一件事是MasterAccount的定义,所以我必须相信你在那里编码了一些导致循环依赖的关系。

如果问题只是您没有想要级联删除一个/所有关系,您可以通过添加

使用Fluent API禁用它
.WillCascadeOnDelete(false)

关系的配置。例如:

   modelBuilder.Entity<User>()
        .HasMany(x => x.Settings)
        .WithRequired()
        .WillCascadeOnDelete(false)

以下是我编写的在我的环境中正常工作的内容:

public class User
{
    public int ID { get; set; }

    /* various user properties */

    public List<ConfigurationSetting> Settings { get; set; }
}

public class ConfigurationSetting
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
    public MasterAccount Account { get; set; }
}

public class MasterAccount
{
    public int ID { get; set; }
    public List<ConfigurationSetting> Settings { get; set; }
    public User User { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<MasterAccount> MasterAccounts { get; set; }
    public DbSet<ConfigurationSetting> Settings { get; set; }
    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
                .HasKey(x => x.ID);

        modelBuilder.Entity<User>()
            .Property(x => x.ID)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
            .HasColumnName("UserId");

        modelBuilder.Entity<User>()
            .HasMany(x => x.Settings)
            .WithMany()
            .Map(m =>
             {
                 m.ToTable("MapUserSettings");
                 m.MapLeftKey("UserId");
                 m.MapRightKey("SettingId");
             });

        base.OnModelCreating(modelBuilder);
    }
}