EFCore Update不会更新数据库中的行

时间:2017-05-10 20:31:50

标签: c# entity-framework entity-framework-core

我的客户端有一个有效负载是一个对象,它的属性是基元,其他对象的属性也是基元。

例如:

public class MainObj
{
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int id {get;set;}
   public string foo {get;set;}
   public OtherObj bar {get;set;}
}

public class OtherObj
{
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int id {get;set;}      
   public int test {get;set;}
}

验证请求后,我会收到用户尝试更新的对象:

var obj = _context.MainObjs.Select(x => new MainObj
{
     id = x.id,
     foo = x.foo,
     bar = x.bar
}).SingleOrDefaultAsync(x => x.id == request.id);

我正在做.Select,因为如果我不这样做,那么bar永远不会被填充。

然后我用来自客户端的内容更新属性:

obj.foo = request.foo;
obj.bar = request.bar;

然后我尝试保存更改:

_context.SaveChangesAsync();

但是,当我这样做时,数据库中没有任何内容。我究竟做错了什么?我过去只使用过EF6,所以如果EFCore对使用外键关系更新对象感到奇怪,我就不知道了。而且要清楚,我的实际对象有更多的属性,但我不相信这是问题。

编辑:我尝试使用.Include语法代替.Select语法,如下所示:

var obj = _context.MainObjs.Include(x =>x.bar).SingleOrDefaultAsync(x => x.id == request.id);

然后我收到The instance of entity type cannot be tracked because another instance of this type with the same key is already being tracked.

的错误

EDIT2:用_context.Update(request)替换所有其他代码正在运行。我很好奇为什么另一种方式不是。

1 个答案:

答案 0 :(得分:2)

陈述......

_context.MainObjs.Select(x => new MainObj { ... })

...不会将任何内容附加到上下文中。它只是创建一个新的MainObj对象,但EF并不知道它。在EF6中,不允许在EF LINQ查询中创建实体类型,以防止这种混淆。

因此,使用_context.MainObjs.Include(x =>x.bar),您会将MainObj及其bar附加到上下文中,并会跟踪其更改。

最后,语句_context.Update(request)request附加到上下文并将其标记为Modified,包括其bar属性的外键。