繁体   English   中英

在Entity Framework 7中更新外键

[英]Updating foreign key in Entity Framework 7

我正在尝试使用Entity Framework 7更新外键。但是它给出了错误:在对象“ X”中找不到属性“ Y”。 我尝试了许多不同的解决方案,但仍然无法正常工作。 示例代码:

class X
{
  property Y {get; set;} -> property Y is a foreign key and also a complex type
}

在表“ X”中,我们有一列“ Y_ID”,即外键。

注意:我只想更新外键。 例如, 最初,类“ X”指向“ NULL”我想更新类“ X”以指向“ Y1”

实体框架7代码:

var x = this.GetX();
this.mainContext.Xs.Attach(x);
var xEntry = this.mainContext.Entry(x);

xEntry.Property("Y").CurrentValue = "Y1"; // Error at this line

await this.mainContext.SaveChangesAsync().ConfigureAwait(false);

详细错误:

找不到实体类型“ X”的属性“ Y”。 确保该属性存在并且已包含在模型中。

编辑

Fabien在评论中建议的方法效果很好。 但是问题在于我们只知道在运行时要更新哪个属性。 如果我使用反射来实现此目的,那么问题是实体框架将对象视为新对象并尝试创建它(插入),然后抛出主键冲突(不允许重复输入)

因此,有没有办法我仍然无法更新像EF中的外键一样的对象属性? (我不知道在编译时的确切属性)。

如果从上下文中获得实体“ X”和“ Y”,则ChangeTracker会自动跟踪它们。 因此,如果为“ X”对象的“ Y”属性分配了从上下文中检索的“ Y”实例并调用SaveChanges或SaveChangesAsync,则EntityFramework会自动为您完成这些工作。

var x = this.GetX();    
x.Y = "Y1";
await this.mainContext.SaveChangesAsync().ConfigureAwait(false);

按照惯例,对象“ X”上的属性“ Y”应为虚拟,以表明它是外键。


编辑1:

如果我理解正确,则希望在运行时动态地更新对象的属性,并使用来自Web api的值。

第一种方式:

像您所做的一样,您可以将“ X”对象附加到上下文实例,以使用EntityState.Unchanged开始跟踪实体,然后标记每个需要更新的属性:

this.mainContext.Xs.Attach(x);
var entry = this.mainContext.entry(x);
entry.Property(p => p.Y).CurrentValue = "Y1";
await this.mainContext.SaveChangesAsync().ConfigureAwait(false);

附加实体时,可以指定GraphBehavior,它告诉EntityFramework是否应遍历导航属性。

第二种方式:

使用DbSet.Update()方法:

this.mainContext.Xs.Update(x);
await this.mainContext.SaveChangesAsync().ConfigureAwait(false);

它会自动开始跟踪状态为EntityState的实体。已修改,所有属性都将标记为已修改。 使用此方法时,请注意,因为所有属性都会更新,如果其中某些属性未在“ X”对象中初始化,则可能会丢失一些数据。 为避免这种情况,您应始终验证输入。


如果要使域模型与任何ORM分离,则应考虑将实体类型和域类型分开。 您可以使用对象映射器(例如Automapper)将实体映射到域类型,反之亦然。 这样一来,您就可以清楚地区分在数据访问层和业务逻辑层的工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM