【问题标题】:One to one mapping in EF Code First and bi-directional navigation propertiesEF Code First 和双向导航属性中的一对一映射
【发布时间】:2011-10-20 18:59:47
【问题描述】:

我的任务是将旧应用程序移植到 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 中做的事情可能吗?

【问题讨论】:

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


    【解决方案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);  
    

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

    【讨论】:

      【解决方案2】:

      尝试添加许可证

      // 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);
      
          }
      

      【讨论】:

      • 现在我收到一个新错误:“System.Data.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 'License_Plant_Source' in relationship 'License_Plant'. 因为从属角色属性不是关键属性,从属角色的多重性的上限必须是“*”。”不知道最后的胡言乱语是怎么回事......
      • 这篇文章 weblogs.asp.net/manavi/archive/2011/05/01/… 说 Code First(以及一般的 EF)本身并不支持一对一的外键关联。
      • 添加 OnModelCreating 的已编辑答案,这有效,但您可能仍需要添加更多内容来将 Plant_Id 定义为外键,其他 FK 也是如此
      猜你喜欢
      • 2022-07-18
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-19
      • 2014-01-20
      • 1970-01-01
      • 2012-03-27
      相关资源
      最近更新 更多