ef关闭oracle外键,EF:如何在不更改架构或丢失数据的情况下从独立关联转换为外键关联...

I have two models that have a bi-directional 0-to-one relationship.

A, B. A may have a B. B may have an A.

Currently these are set up with navigational properties within each class, WITHOUT foreign key properties (set using fluent syntax)

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()

.HasOptional(b => b.A)

.WithOptionalPrincipal()

.Map(b => b.MapKey("AId"));

modelBuilder.Entity()

.HasOptional(p => p.B)

.WithOptionalPrincipal()

.Map(p => p.MapKey("BId"));

So far things are working fine, as expected.

I would now like to expose these ID properties in my entities, so that to aid in updating disconnected entity relationships.

If I remove the maps, and then try to use the keys, it appears to work, but the migration decides to drop the FK columns, and then re-add them with a different name. This will break all my existing data.

I tried to rewrite the fluent mapping to use HasMany().HasForeignKey(), but that didn't work either. (Even though its not really many, that seems to be required to get the HasForeignKey method?)

What is the right way to upgrade this relationship while keeping the schema the same to preserve existing data in the database?

Solutions1

You current mapping generates the following migration:

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

As you can see, it is a 1-n relationship, not 1-0.1. The relationship "A may have a B; B may have an A" is not possible.

A may have B, but only one B, so B's primary key should also be A's foreign key.

That's ok. That's how a 1-0.1 relationship works. But on the other side, you want to do same.

B may have an A, but only one A, so A's primary key should also be B's foreign key.

That's not ok, you are trying to make a "real 1-1 relationship", which is not possible because you can't insert 2 rows at the same time.

What you want is a 1-n relationship. So, modify your classes as follow:

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

}

Mapping:

modelBuilder.Entity()

.HasOptional(i => i.B)

.WithMany()

.HasForeignKey(i => i.BId);

modelBuilder.Entity()

.HasOptional(i => i.A)

.WithMany()

.HasForeignKey(i => i.AId);

It generates the following migration (the properties' names might be inverted. In that case, just change BId to AId and AId to 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);

Hope it helps!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值