如何在代码优先EF5中使用真正的自引用实体?

Lev*_*kon 7 c# sql entity-framework

关于这个主题有几个问题,但我的问题非常具体到真正的自我引用.其他问题的所有例子都是循环引用,在这种情况下对我没有帮助.

让我们说我有这个模型:

public class User
{
    [Key]
    public int Id { get; set; }

    ...

    public int CreatedByUserId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

而这张地图:

public class UserMap : EntityTypeConfiguration<User>
{
    public UserMap()
    {
        this.HasRequired(a => a.CreatedByUser)
            .WithMany()
            .HasForeignKey(u => u.CreatedByUserId);
    }
}
Run Code Online (Sandbox Code Playgroud)

迁移生成具有此代码的数据库后,我可以在SQL Management Studio中手动添加Id = 1和CreatedByUserId = 1的用户,这样就可以告诉我这样的自引用可以正常工作.

但是,当使用EF创建用户时,我遇到了"无法确定依赖操作的有效排序"问题.关于这个问题有很多问题涉及一个新实体,它引用另一个在第一个实体上有外键的新实体,这是一个循环引用.在这些情况下的解决方案是首先保存实体之一或在循环实体外键上具有可空id.我不能做其中任何一个,因为第一个是不可能的,第二个是外部约束,我不能有可空的id.

所以,看看如何通过手动添加条目来实现这一点,我可以假设它是EF5的限制.有什么工作?

Kha*_*han 1

您仍然可以满足您的界面并通过添加另一个属性作为可空支持者来执行先保存然后设置CreatedByUserId方法:

public class User : ICreatable 
{
    [Key]
    public int Id { get; set; }

    ...

    public int CreatedByUserId 
    { 
        get 
        {
            if (!_CreatedByUserId.HasValue)
                //throw new exception, something went wrong.

            return _CreatedByUserId;
        }       
        set 
        {
            _CreatedByUserId = value;
        }
    }

    int? _CreatedByUserId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)