【问题标题】:EF 4.3 relationships not rightEF 4.3 关系不正确
【发布时间】:2012-04-24 20:50:07
【问题描述】:
public class ObjectA
{
    public Guid Id {get; set;}
    public virtual ObjectB Objectb {get; set;}
}

public class ObjectB
{
    public Guid Id {get; set;}
    public Guid ObjectAId {get; set;}
    public virtual ObjectA ObjectA {get; set;}
}

我没有运气让关系正确。

modelBuilder.Entity<ObjectA>()
    .HasRequired(p => p.ObjectB)
    .WithRequiredPrincipal()
    .WillCascadeOnDelete(false); 

创建了两个关系:

  1. Object.ObjectA/ObjectA.Id
  2. ObjectA.Id/ObjectB.Id

如何让 EF 停止创建关系 #2?这不正确,也不是我想要的。

错误:

modelBuilder.Entity<ObjectA>().HasRequired(x => x.Objectb).WithRequiredPrincipal(x => x.ObjectA);

    ALTER TABLE [dbo].[ObjectBs]  WITH CHECK ADD  CONSTRAINT [FK_ObjectBs_ObjectAs_Id] FOREIGN KEY([Id])
    REFERENCES [dbo].[ObjectAs] ([Id])
    GO 

几乎正确:

modelBuilder.Entity<ObjectA>().HasOptional(x => x.Objectb).WithOptionalPrincipal(x => x.ObjectA);

ALTER TABLE [dbo].[ObjectBs]  WITH CHECK ADD  CONSTRAINT [FK_ObjectBs_ObjectAs_ObjectA_Id] FOREIGN KEY([ObjectA_Id])
REFERENCES [dbo].[ObjectAs] ([Id])
GO

添加了一个额外的列,所以我在 ObjectB 中得到了 ObjectAId 和 ObjectA_Id。

modelBuilder.Entity<ObjectA>().HasOptional(x => x.Objectb).WithOptionalPrincipal(x => x.ObjectA).Map(x => x.MapKey("ObjectAId"));

抛出异常:类型中的每个属性名称都必须是唯一的。已定义属性名称“ObjectAId”。

【问题讨论】:

    标签: c# entity-framework entity-framework-4 ef-code-first entity-framework-4.3


    【解决方案1】:

    ObjectB中移除外键属性:

    public class ObjectA
    {
        public Guid Id {get; set;}
        public virtual ObjectB Objectb {get; set;}
    }
    
    public class ObjectB
    {
        public Guid Id {get; set;}
        public virtual ObjectA ObjectA {get; set;}
    }
    

    并将此映射与 Fluent API 一起使用:

    modelBuilder.Entity<ObjectA>()
        .HasRequired(a => a.ObjectB)
        .WithRequiredPrincipal(b => b.ObjectA)
        .WillCascadeOnDelete(false); 
    

    需要去掉外属性的原因是EF不支持一对一的外键关联,只支持One-to-One Shared Primary Key Associations

    如果您想要一个一对一的外键关联,其中依赖项有一个外键作为与主键不同的唯一键 there is only a workaround 将您的模型映射为一对多关系而无需导航关系多方面的属性和数据库中的唯一约束,如下所示:

    public class ObjectA
    {
        public Guid Id {get; set;}
    }
    
    public class ObjectB
    {
        public Guid Id {get; set;}
        public Guid ObjectAId {get; set;}
        public virtual ObjectA ObjectA {get; set;}
    }
    
    modelBuilder.Entity<ObjectB>()
        .HasRequired(b => b.ObjectA)
        .WithMany()
        .HasForeignKey(b => b.ObjectAId)
        .WillCascadeOnDelete(false); 
    

    【讨论】:

    • 感谢您的解释。我希望避免删除外键,因为它已被使用。我可以重构那个代码。
    【解决方案2】:

    这是在按照 Slauma 的建议删除外键属性后最终起作用的方法。

        modelBuilder.Entity<ObjectA>()
        .HasOptional(x => x.ObjectB)
        .WithRequired(x => x.ObjectA)
        .Map(x => x.MapKey("ObjectAId"))
        .WillCascadeOnDelete(true);
    

    我必须映射属性,否则外键是在主键上创建的。

    【讨论】:

    • 这真的很困扰我。我想在属性中映射“ObjectAId”,因为我使用它。
    【解决方案3】:

    我想你想要:

    modelBuilder.Entity<ObjectA>()
        .HasRequired(p => p.ObjectB)
        .HasForeignKey(p => p.ObjectAId);
    

    取自http://msdn.microsoft.com/en-us/data/hh134698

    【讨论】:

      猜你喜欢
      • 2012-03-06
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 2012-04-08
      • 2017-09-30
      • 2017-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多