EF Code First中的一对一映射和双向导航属性

时间:2011-10-20 18:59:47

标签: c# asp.net-mvc-3 entity-framework ef-code-first

我的任务是将旧的应用程序移植到MVC 3,并希望首先使用EF的代码来复制其现有的数据库架构。当前的代码库充斥着硬编码的SQL命令,因此我提出的模型必须与当前系统所期望的“兼容”。我知道我可以使用EF的Database First来做到这一点,但现有的架构非常简单,我认为没有理由不先使用代码,因为我希望在我们从旧的硬编码数据库迁移时建立坚实的基础相互作用。

我需要POCO看起来像什么:

public class Owner
{
    [Key]
    public Guid Owner_Id { get; set; }

    // Properties
    public string ContactName { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }

    // Navigational properties
    public virtual ICollection<Plant> Plants { get; set; }
}

public class Plant
{
    [Key]
    public Guid Plant_Id { get; set; }

    // Properties
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }

    // Foreign Keys
    public Guid Owner_Id { get; set; }

    // Navigational properties
    public virtual Owner Owner { get; set; }
    public virtual License License { get; set; }
}

public class License
{
    [Key] public Guid License_Id { get; set; }

    // Properties
    public int Total { get; set; }
    public int Users { get; set; }
    public string Key { get; set; }

    // Foreign Keys
    public Guid Plant_Id { get; set; }

    // Navigational properties
    public virtual Plant Plant { get; set; }
}

在尝试创建上下文时,它给了我这个错误:

“无法确定类型'License'和'Plant'之间关联的主要结束。必须使用关系流畅API或数据注释显式配置此关联的主要结尾。”

我意识到Plant应该对License_Id具有可空的FK引用,并且该许可证不应具有Plant_Id的FK。但这些是我已经处理过的卡片。我想在EF做什么?

2 个答案:

答案 0 :(得分:1)

尝试添加许可证

// Foreign Keys
public Guid Plant_Id { get; set; }

// Navigational properties
[ForeignKey("Plant_Id")]
public virtual Plant Plant { get; set; }

让它知道这是外键,对于其他外键也是如此。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Plant>()
            .HasOptional(e => e.License)
            .WithOptionalPrincipal(e => e.Plant);

    }

答案 1 :(得分:1)

public class Plant
{
    public Guid PlantID { get; set; }
    public virtual License License { get; set; }
} 

public class License
{
     // No need to have a PlantID foreign key since the foreign key.
     public Guid LicenseID { get; set; }
     public virtual Plant Plant { get; set; }
}

在fluent-api中(在你的上下文课中):

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Plant>().HasOptional(p => p.License).WithRequired(l => l.Plant);  

唯一的降级是你实际上将一个定义为零或一个。 (可以在代码中处理。但仍然......)有关一对一关系的更多信息,请查看Entity Framework Code First One to One Relationship