Entity Framework 更新时不保存所有属性
Entity Framework not saving all properties on update
我正在尝试使用自定义 getter 和 setter 更新实体,但如果我编辑实体上的任何其他 属性,它们将不会被保存。我有一个 DTO,它映射到检索到的实体。
DTO:
public class MyEntityDto
{
public string Id { get; set; }
public string Name { get; set; }
public bool Enabled { get; set; }
public Dictionary<string, string> Settings { get; set; }
}
实体:
public class MyEntity
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
public virtual bool Enabled { get; set; }
public Dictionary<string, string> Settings { get; set; }
public virtual string SettingsJson
{
get { return JsonConvert.SerializeObject(Settings); }
set
{
Settings = JsonConvert.DeserializeObject<Dictionary<string, string>>(value);
}
}
}
更新函数:
public async Task UpdateAsync(dto MyEntityDto)
{
var existingEntity = await _myRepository.GetByIdAsync(dto.Id);
existingEntity.Name = dto.Name;
existingEntity.Enabled = dto.Enabled;
existingEntity.Settings = dto.Settings;
await _myRepository.Update(existingEntity);
// save changes happens at end of request
}
我的 SettingsJson
没有更新。我已经完成了它并且 existingEntity.SettingsJson
和 existingEntity.Settings
都有正确的数据。 Name
和 Enabled
会更新。
但是,如果我删除 Name
和 Enabled
的分配,SettingsJson
会得到更新。
它确实适用于实体创建,但不适用于更新。我还想指出我无权访问 DbContext
.
我猜 Entity Framework 不知道它应该在数据库中更新 SettingsJson
,因为您永远不会在代码中直接修改它。是的,您修改了 SettingsJson
的 getter 中使用的 Settings
对象,但是 Entity Framework 不会那样跟踪对象。
在修改 Settings
对象之后尝试此操作,但在进行实际更新之前:
_myDbContext.Entry(existingEntity).Property(e => e.SettingsJson).IsModified = true;
然而,此代码假定您的 DbContext
已暴露,但事实可能并非如此。
编辑:
如果你没有权限访问DbContext
,你必须直接设置SettingsJson
属性为了让 Entity Framework 在数据库中更新它。我知道在您当前的实现中,您永远不需要担心更新实际字典和字典的 JSON 表示,但是 Entity Framework 不可能做到这一点。你必须尝试这样的事情:
public virtual string SettingsJson { get; set; } // just an auto-implemented property
...
existingEntity.Settings = dto.Settings;
existingEntity.SettingsJson = JsonConvert.SerializeObject(dto.Settings);
// save changes
另一个解决方案可以直接在Settings
的setter中设置SettingsJson
,像这样:
private Dictionary<string, string> settings // private backing field
public Dictionary<string, string> Settings
{
get { return settings; }
set
{
settings = value;
SettingsJson = JsonConvert.SerializeObject(dto.Settings); // EF tracks this
}
}
但是,如果在设置后向字典添加元素,则需要重新序列化字典,才能更新JSON字符串。您可以通过使用某种可观察字典来动态解决此问题,但请确保它仅在需要时(在调用更新数据库之前)将字典序列化一次。
这不是真正的解决方案,但值得深思。数据库不理解字典。你知道的,这就是你使用 JSON 来帮助你的原因。但是,为什么不简单地添加一个 Setting
table 到你的数据库模型呢?
我正在尝试使用自定义 getter 和 setter 更新实体,但如果我编辑实体上的任何其他 属性,它们将不会被保存。我有一个 DTO,它映射到检索到的实体。
DTO:
public class MyEntityDto
{
public string Id { get; set; }
public string Name { get; set; }
public bool Enabled { get; set; }
public Dictionary<string, string> Settings { get; set; }
}
实体:
public class MyEntity
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
public virtual bool Enabled { get; set; }
public Dictionary<string, string> Settings { get; set; }
public virtual string SettingsJson
{
get { return JsonConvert.SerializeObject(Settings); }
set
{
Settings = JsonConvert.DeserializeObject<Dictionary<string, string>>(value);
}
}
}
更新函数:
public async Task UpdateAsync(dto MyEntityDto)
{
var existingEntity = await _myRepository.GetByIdAsync(dto.Id);
existingEntity.Name = dto.Name;
existingEntity.Enabled = dto.Enabled;
existingEntity.Settings = dto.Settings;
await _myRepository.Update(existingEntity);
// save changes happens at end of request
}
我的 SettingsJson
没有更新。我已经完成了它并且 existingEntity.SettingsJson
和 existingEntity.Settings
都有正确的数据。 Name
和 Enabled
会更新。
但是,如果我删除 Name
和 Enabled
的分配,SettingsJson
会得到更新。
它确实适用于实体创建,但不适用于更新。我还想指出我无权访问 DbContext
.
我猜 Entity Framework 不知道它应该在数据库中更新
SettingsJson
,因为您永远不会在代码中直接修改它。是的,您修改了SettingsJson
的 getter 中使用的Settings
对象,但是 Entity Framework 不会那样跟踪对象。在修改
Settings
对象之后尝试此操作,但在进行实际更新之前:_myDbContext.Entry(existingEntity).Property(e => e.SettingsJson).IsModified = true;
然而,此代码假定您的
DbContext
已暴露,但事实可能并非如此。
编辑:
如果你没有权限访问
DbContext
,你必须直接设置SettingsJson
属性为了让 Entity Framework 在数据库中更新它。我知道在您当前的实现中,您永远不需要担心更新实际字典和字典的 JSON 表示,但是 Entity Framework 不可能做到这一点。你必须尝试这样的事情:public virtual string SettingsJson { get; set; } // just an auto-implemented property ... existingEntity.Settings = dto.Settings; existingEntity.SettingsJson = JsonConvert.SerializeObject(dto.Settings); // save changes
另一个解决方案可以直接在
Settings
的setter中设置SettingsJson
,像这样:private Dictionary<string, string> settings // private backing field public Dictionary<string, string> Settings { get { return settings; } set { settings = value; SettingsJson = JsonConvert.SerializeObject(dto.Settings); // EF tracks this } }
但是,如果在设置后向字典添加元素,则需要重新序列化字典,才能更新JSON字符串。您可以通过使用某种可观察字典来动态解决此问题,但请确保它仅在需要时(在调用更新数据库之前)将字典序列化一次。
这不是真正的解决方案,但值得深思。数据库不理解字典。你知道的,这就是你使用 JSON 来帮助你的原因。但是,为什么不简单地添加一个
Setting
table 到你的数据库模型呢?