【问题标题】:Entity Framework Many To Many with TPT Approach实体框架多对多与 TPT 方法
【发布时间】:2014-05-21 08:34:34
【问题描述】:

我试图达到的是 AbstractUser 和 Plant 之间的 NM 关系,用于 TPT 继承。

当我尝试配置关系时,

modelBuilder.Entity<Plant>().HasMany(c => c.RemindedByUsers).WithMany().Map(m =>
{
    m.ToTable("UserHasRemindedPlant");
});

我得到以下异常:

附加信息:引入 FOREIGN KEY 约束 'FK_dbo.UserHasRe MindPlant_dbo.AbstractUsers_AbstractUser_Id' on 表 'UserHasRemittedPlant' 可能会导致循环或多个级联 路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改 其他 FOREIGN KEY 约束。

如何对 tpt 抽象实体上的多对多关系设置 ON DELETE 或 ON UPDATE 操作?

当我使用上面的行时,一切正常,但我需要对其他实体使用此约定。

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

这里是我的实体类:

抽象用户

public abstract class AbstractUser
{
    protected AbstractUser()
    {
        RemindedPlants = new Collection<Plant>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    ...


    [Required]
    public SchoolYear SchoolYear { get; set; }

    public virtual ICollection<Plant> RemindedPlants { get; private set; }
}

学生

[Table("Student")]
public class Student : AbstractUser
{
    //some unrelevant props here

}

老师

[Table("Teacher")]

public class Teacher : AbstractUser
{
    //some unrelevant props here

}

【问题讨论】:

  • 问题出在其他地方。如果在删除 OneToManyCascadeDeleteConvention 时它有效,则问题不可能是多对多关系。例如,Plant 是否有(必需的)对用户(AbstractUser 或派生用户之一)的引用?这确实会导致从AbstractUser 表到UserHasRemindedPlant 表的多个删除路径并抛出异常。

标签: c# entity-framework many-to-many table-per-type


【解决方案1】:

您必须使用 Fluent API .WillCascadeOnDelete(false) 禁用级联删除:

modelBuilder.Entity<Plant>().HasMany(c => c.RemindedByUsers).WithMany().WillCascadeOnDelete(false).Map(m =>{
m.ToTable("UserHasRemindedPlant");});

【讨论】:

  • 感谢您的回复。出于某种原因,Visual Studio 无法在 WithMany() 之后解析 WillCascadeOnDelete(false)。这在 EF6 之后发生了变化吗?
  • 您使用的是哪个版本的 EF?
  • EF:6.0.2 Dot.Net:4.5
  • 那么使用 WillCascadeOnDelete(false) 应该没有问题。在 WithMany() 之后,你在 AutoComplete 上得到了什么?
  • GetType、地图、MapToStoredProcedures。如果我选择 WithOptional 或 WithRequired “WillCascadeOnDelete”可用,但在 WithMany 之后不可用:/
【解决方案2】:

试试这个:

modelBuilder.Conventions.Remove();

见:https://stackoverflow.com/a/13705637/491181

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多