【问题标题】:Entity Framework 4.1 InverseProperty Attribute and ForeignKeyEntity Framework 4.1 InverseProperty 属性和ForeignKey
【发布时间】:2011-08-15 06:20:17
【问题描述】:

我将使用外键在 Employee 和 Team 实体之间创建两个引用。 所以我定义了两个实体如下

public class Employee
{
    public int EmployeeId { get; set; }
    public string Name { get; set; }

    [ForeignKey("FirstTeam")]
    public int FirstTeamId { get; set; }

    [InverseProperty("FirstEmployees")]
    public virtual Team FirstTeam { get; set; }

    [ForeignKey("SecondTeam")]
    public int SecondTeamId { get; set; }

    [InverseProperty("SecondEmployees")]
    public virtual Team SecondTeam { get; set; }
}

public class Team
{
    public int Id { get; set; }
    public string TeamName { get; set; }

    [InverseProperty("FirstTeam")]
    public virtual ICollection<Employee> FirstEmployees { get; set; }

    [InverseProperty("SecondTeam")]
    public virtual ICollection<Employee> SecondEmployees { get; set; }
}

我认为理论上是正确的,但它显示异常如下:

{"Introducing FOREIGN KEY constraint 'Employee_SecondTeam' on table 'Employees' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.\r\nCould not create constraint. See previous errors."}

谁能帮帮我?

提前致谢 权

【问题讨论】:

    标签: c# mapping entity entity-framework-4.1 cascading-deletes


    【解决方案1】:

    上一个答案都是正确的,但有一件事是错误的

        modelBuilder.Entity<Employee>()
                    .HasRequired(e => e.SecondTeam)
                    .WithMany(t => t.SecondEmployees)
                    .HasForeignKey(e => e.SecondTeamId) // mistake
                    .WillCascadeOnDelete(false);
    

    FirstTeamId 而不是SecondTeamId 将导致SecondTeam navigation 中的属性将始终为FirstTeam

    【讨论】:

      【解决方案2】:

      理论上是正确的,但 SQL 服务器(不是实体框架)不喜欢它,因为您的模型允许单个员工同时成为第一和第二团队的成员。如果Team 被删除,这将导致多个删除路径指向同一个Employee 实体。

      如果您将外键定义为强制(不可为空),则这不能与默认情况下在 EF 代码中首先使用的级联删除一起使用。

      如果你想避免异常,你必须使用流畅的映射:

      public Context : DbContext
      {
          public DbSet<Employee> Employees { get; set; }
          public DbSet<Team> Teams { get; set; }
      
          protected override void OnModelCreating(DbModelBuilder modelBuilder)
          {
              base.OnModelCreating(modelBuilder);
      
              modelBuilder.Entity<Employee>()
                          .HasRequired(e => e.SecondTeam)
                          .WithMany(t => t.SecondEmployees)
                          .HasForeignKey(e => e.FirstTeamId)
                          .WillCascadeOnDelete(false);
      
              ...
          }
      }
      

      这将导致您必须在删除团队之前手动删除 SecondTeam 的成员。

      【讨论】:

      • 但是,如果您让 EF 生成密钥,它将使它们可以为空(可选关系)。使用流畅映射时,它还将使用列名作为外键。
      • 谢谢拉迪斯拉夫。这正是我想要的。
      • 抱歉删除了我的 cmets。但是,如果是这样,如果我将外键属性定义为像 public int 一样可以为空,是否有可能? FirstTeamId {get;设置;} ?
      • @LadislavMrnka 是否有属性而不是 fluent?
      • 我发现我必须使用 modelBuilder.Conventions.Remove();让类似的事情发挥作用
      猜你喜欢
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多