EF 4.1映射问题

时间:2011-05-22 17:34:45

标签: entity-framework entity-framework-4.1 code-first

我有一个与自己有关系的课程:

public class Person
{
    public long ID { get; set; }
    public string Name { get; set; }

    public virtual Person Mother { get; set; }
    public virtual Person Father { get; set; } 
}

当EF 4.1尝试映射此类时,我收到以下错误: '无法确定类型'Model.Person'和'Model.person'之间关联的主要结束。必须使用关系流畅API或数据注释显式配置此关联的主要结尾。'

我已经尝试了主题EF 4.1 - Model Relationships的解决方案但没有成功。

我如何解决这个问题?

谢谢!

3 个答案:

答案 0 :(得分:9)

因为它自然是一对多关系(一个人必须有一个父亲和一个母亲,但可以有许多儿子和女儿)我会像这样建模:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasRequired(p => p.Father)
        .WithMany();

    modelBuilder.Entity<Person>()
        .HasRequired(p => p.Mother)
        .WithMany();
}

这将按照惯例在名为Mother_IDFather_ID的数据库表中创建两个必需的外键。

修改

如果您希望能够创建没有母亲和父亲的人,您可以建立关系可选而非所需:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasOptional(p => p.Father)
        .WithMany();

    modelBuilder.Entity<Person>()
        .HasOptional(p => p.Mother)
        .WithMany();
}

然后数据库表中的外键可以为空。

如果您不喜欢外键(Mother_IDFather_ID)的默认列名,您可以自定义映射中的列名称:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Person>()
        .HasOptional(p => p.Father)
        .WithMany()
        .Map(m => m.MapKey("FatherID"));

    modelBuilder.Entity<Person>()
        .HasOptional(p => p.Mother)
        .WithMany()
        .Map(m => m.MapKey("MotherID"));
}

答案 1 :(得分:0)

对于其他任何想知道的人来说,这显然不能通过DataAnnotation属性来完成,但只能流利地配置。 http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/08bba96a-20b2-4a3c-9e0e-a5475b703dfe

答案 2 :(得分:0)

这有点奇怪,但你可以这样做而不需要像模型构建器一样的垃圾:

public class RecursiveModel
{
    public long Id { get; set; }
    public string Name { get; set; }

    public RecursiveModel Father { get; set; }
    public RecursiveModel Mother { get; set; }
    public ICollection<RecursiveModel> Children { get; set; }
}

因此,基本上这些模型中的一个将具有其子项列表,并且如果例如这是母亲,则它们中的每一个都将其Mother_Id和RecursiveModel_Id设置为该对象。你需要每次都明确地连接它,理想情况是通过辅助方法,如:

    public void AddAsMotherOfChild(RecursiveModel child)
    {
        Children.Add(child);
        child.Mother = this;
    }

    public void AddAsFatherOfChild(RecursiveModel child)
    {
        Children.Add(child);
        child.Father = this;
    }

不完美但它确实避免了模型构建器代码,对我而言,随着时间的推移,至少会变得脆弱和军团。