没有外键的导航属性,还是流畅的api版本?

时间:2015-11-07 14:25:32

标签: c# entity-framework ef-code-first entity-framework-6 ef-migrations

我有一个用户表,其中一个用户可以是另一个用户的管理员(这是可选的,因此int? IdManager

[Table("users")]
public partial class User
{
    #region Properties
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    [Required]
    [Column("Id")]
    public int Id { get; set; }
    #endregion

    #region DataNavigation
    /// <summary>
    /// Navigation Id for getting parent Field
    /// WARNING: this works, but need to remove foreign key creation in migration file !
    /// </summary>
    [ForeignKey("Manager")]
    [Column("IdManager")]
    public int? IdManager { get; set; }

    /// <summary>
    /// Navigation object to parent Field
    /// </summary>
    [ScriptIgnore]
    [JsonIgnore]
    [IgnoreDataMember]
    public virtual User Manager { get; set; }
    #endregion
}

现在在代码中,上面的代码生成了这个

public partial class manager : DbMigration
{
    public override void Up()
    {
        AddColumn("users", "IdManager", c => c.Int());
        CreateIndex("users", "IdManager");
        AddForeignKey("users", "IdManager", "users", "Id");
    }

    public override void Down()
    {
        DropForeignKey("users", "IdManager", "users");
        DropIndex("users", new[] { "IdManager" });
        DropColumn("users", "IdManager");
    }
}

但是在使用Cannot add foreign key constraint

更新数据库时它会中断

但是,如果我删除外键创建

public partial class manager : DbMigration
{
    public override void Up()
    {
        AddColumn("users", "IdManager", c => c.Int());
        CreateIndex("users", "IdManager");
    }

    public override void Down()
    {
        DropIndex("users", new[] { "IdManager" });
        DropColumn("users", "IdManager");
    }
}

dbContext和Linq

中的一切正常

...但是,我必须将[ForeignKey("Manager")]留在我的用户对象上(对于linq和dbcontext),这不是那么好,因为在以后的某个时候它肯定会再次面对某些人。

关于如何通过数据属性或流畅的api正确映射这个问题的任何想法?

谢谢!

2 个答案:

答案 0 :(得分:2)

我还没有测试过它,但是用流畅的api应该是这样的:

modelBuilder.Entity<User>()
   .HasOptional(u=>u.Manager)
   .WithMany()
   .HasForeignKey(u=>u.IdManager)
   .WillCascadeOnDelete(false);

因此,用户有一个可选的管理器,可以有许多用户链接到它,而管理器没有一组用户(WithMany不带参数),具有给定的外键属性(IdManager)并禁用级联删除。

答案 1 :(得分:0)

我尝试了另一种方式,创建了一个这样的Employee表并添加为模型,它让我得到了这个:

public partial class Employee
{
    public Employee()
    {
        Subordinates = new HashSet<Employee>();
    }
    public int Id { get; set; }
    public string Name { get; set; }
    public int? ManagerId { get; set; }
    public virtual Employee Manager { get; set; }
    public virtual ICollection<Employee> Subordinates { get; set; }
}

public class EmployeeConfiguration: EntityTypeConfiguration<Employee>
{
    public EmployeeConfiguration()
    {
        ToTable("EmployeeDbContext", "dbo");
        HasKey(p => p.Id).Property(p => p.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(p => p.Name).HasMaxLength(50);
        HasMany(p => p.Subordinates).WithOptional(p => p.Manager)
                                 .HasForeignKey(p => p.ManagerId);
    }
}