我正在尝试使用自定义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
都有正确的数据。 <{1}}和Name
会更新。
但是,如果删除Enabled
和Name
的分配,Enabled
会更新。
它确实可以在实体创建时使用,而不是在更新时。我还想指出我无法访问SettingsJson
。
答案 0 :(得分:3)
我猜测实体框架并不知道它应该更新数据库中的SettingsJson
,因为您从不直接在代码中修改它。是的,您修改Settings
的getter中使用的SettingsJson
对象,但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
另一个解决方案可能是在SettingsJson
的设置器中直接设置Settings
,如下所示:
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
表添加到数据库模型中?