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

博客讨论了在Entity Framework中处理双向0-1关系时遇到的问题,即在尝试暴露外键属性以辅助更新断开的实体关系时,迁移导致外键列被删除并重新创建,破坏了现有数据。解决方案是将关系调整为1-n关系,通过添加可空外键属性来保持数据一致性,并提供了修改后的类映射示例。
摘要由CSDN通过智能技术生成

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!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值