如何更新EntityFramework核心代码第一个对象,包括所有属性也是复杂的对象?

时间:2017-05-10 18:10:02

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

我有一个类Character,其属性是基元和复杂对象的混合,其中一些对象具有属性也是复杂对象。所有这些都在数据库中表示,每个类都有自己的表,通过EFCore Code First生成。

这是我想要完成的一个小例子:

public class Character
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public string Race { get; set; }
public DeathSaves DeathSaves{ get; set; }
public SavingThrows SavingThrows { get; set; }
}


public class DeathSaves
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public bool? Success1 { get; set; }
    public bool? Success2 { get; set; }
    public bool? Success3 { get; set; }
    public bool? Failure1 { get; set; }
    public bool? Failure2 { get; set; }
    public bool? Failure3 { get; set; }
}

public class SavingThrows
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public SavingThrow Strength { get; set; }
    public SavingThrow Dexterity { get; set; }
    public SavingThrow Constitution { get; set; }
    public SavingThrow Intelligence { get; set; }
    public SavingThrow Wisdom { get; set; }
    public SavingThrow Charisma { get; set; }
}

public class SavingThrow
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public bool? Proficient { get; set; }
    public int? Value { get; set; }
}

如上所示,我的Character类包含DeathSaves,它是基元的对象,SavingThrows是包含多个属性的对象,SavingThrow秒。

我知道在我的控制器中,我已经尝试了

var dbchar = _context.Characters.SingleOrDefault(x => x.Id == character.id);
dbchar = character;
_context.SaveChanges();

其中character从客户端发送,但不会更新数据库中的任何内容。我也试过做_context.Characters.Attach(character),但似乎也没有更新任何东西。我在这做错了什么?

1 个答案:

答案 0 :(得分:1)

这段代码......

var dbchar = _context.Characters.SingleOrDefault(x => x.Id == character.id);
dbchar = character;

...通过引用一些未跟踪的对象来替换对上下文缓存中的字符对象的引用。那一刻你丢失了被跟踪物体的手柄。它与:

相同
var dbchar = new Character { Name = "John" }; // character1
dbchar = new Character { Name = "Pete" }; // character2

对象character1超出了范围,但它仍然是John。

执行此操作的正确方法是将character的值复制到dbchar

var dbchar = _context.Characters.Find(character.id);
db.Entry(cbchar).CurrentValues.SetValues(character);

或将character附加到上下文并将其标记为已修改:

db.Attach(character);
db.Entry(character).State = EntityState.Modified;

(使用ef-core v.1.1.2)