【问题标题】:EF : How do I convert from Independent Association to Foreign Key Association without changing schema or losing dataEF:如何在不更改架构或丢失数据的情况下从独立关联转换为外键关联
【发布时间】:2016-04-17 08:25:59
【问题描述】:

我有两个具有双向 0 对一关系的模型。

A,B。A可能有B。B可能有A。

目前这些都是在每个类中设置导航属性,没有外键属性(使用流畅的语法设置)

public class A{
[key]
public int Id {get;set;}
public B B {get;set;}}

public class B{
[key]
public int Id {get;set;}
A A {get;set;}
}

     modelBuilder.Entity<B>()
            .HasOptional(b => b.A)
            .WithOptionalPrincipal()
            .Map(b => b.MapKey("AId"));

        modelBuilder.Entity<A>()
            .HasOptional(p => p.B)
            .WithOptionalPrincipal()
            .Map(p => p.MapKey("BId"));

到目前为止,一切正常,正如预期的那样。

我现在想在我的实体中公开这些 ID 属性,以便帮助更新断开的实体关系。

当我只添加属性时,每个 error 0019: Each property name in a type must be unique on ID field 都会出现“重复名称”错误

如果我删除映射,然后尝试使用键,它似乎可以工作,但迁移决定删除 FK 列,然后用不同的名称重新添加它们。这会破坏我现有的所有数据。

我尝试重写 fluent 映射以使用 HasMany().HasForeignKey(),但这也不起作用。 (尽管它并不多,但似乎需要获取 HasForeignKey 方法?)

在保持架构相同以保留数据库中现有数据的同时升级这种关系的正确方法是什么?

【问题讨论】:

    标签: c# entity-framework foreign-keys


    【解决方案1】:

    您当前的映射会生成以下迁移:

    CreateTable(
        "dbo.B",
        c => new
            {
                Id = c.Int(nullable: false, identity: true),
                BId = c.Int(),
            })
        .PrimaryKey(t => t.Id)
        .ForeignKey("dbo.A", t => t.BId)
        .Index(t => t.BId);
    
    CreateTable(
        "dbo.A",
        c => new
            {
                Id = c.Int(nullable: false, identity: true),
                AId = c.Int(),
            })
        .PrimaryKey(t => t.Id)
        .ForeignKey("dbo.B", t => t.AId)
        .Index(t => t.AId);
    

    如您所见,这是一个 1-n 关系,而不是 1-0.1。 “A 可能有 B;B 可能有 A”的关系是不可能的。

    A可能有B,但只有一个B,所以B的主键也应该是A的外键。

    没关系。这就是 1-0.1 关系的运作方式。但另一方面,你也想做同样的事情。

    B可能有一个A,但只有一个A,所以A的主键也应该是B的外键。

    这不行,你正在尝试建立“真正的 1-1 关系”,这是不可能的,因为你不能同时插入 2 行。

    你想要的是一个 1-n 的关系。所以,修改你的类如下:

    public class A
    {
        [Key]
        public int Id { get; set; }
    
        public int? BId { get; set; }
        public B B { get; set; }
    }
    
    public class B
    {
        [Key]
        public int Id { get; set; }
    
        public int? AId { get; set; }
        public A A { get; set; }
    }
    

    映射:

    modelBuilder.Entity<A>()
        .HasOptional(i => i.B)
        .WithMany()
        .HasForeignKey(i => i.BId);
    
    modelBuilder.Entity<B>()
        .HasOptional(i => i.A)
        .WithMany()
        .HasForeignKey(i => i.AId);
    

    它会生成以下迁移(属性的名称可能会颠倒。在这种情况下,只需将 BId 更改为 AId,将 AId 更改为 BId):

    CreateTable(
        "dbo.B",
        c => new
            {
                Id = c.Int(nullable: false, identity: true),
                AId = c.Int(),
            })
        .PrimaryKey(t => t.Id)
        .ForeignKey("dbo.A", t => t.AId)
        .Index(t => t.AId);
    
    CreateTable(
        "dbo.A",
        c => new
            {
                Id = c.Int(nullable: false, identity: true),
                BId = c.Int(),
            })
        .PrimaryKey(t => t.Id)
        .ForeignKey("dbo.B", t => t.BId)
        .Index(t => t.BId);
    

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-14
      • 2012-09-18
      • 2013-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多