>我获得了List< MyEntity>从数据库(它可以简单地通过DbContext.MyEntities.ToList()的所有记录或通过某些过滤条件记录 – 它没关系).
>然后将这些实体传递给用户可以更改属性的某个UI.他的行为是不可预测的:他可以改变每个实体的每一个属性,或者他只能改变一个实体的一个属性(他甚至根本不能进行任何改变).
>之后我需要将更新传递给数据库.
为了实现这种情况,我找到了两种可能的解决方案:
1)在整个场景中保持连接打开.所以它会像这样工作:
MyDbContext.Database.Connection.open(); List<MyEntity> EntitiesList = MyDbContext.MyEntities.ToList(); //passing EntitiesList to the UI,where user can change them EntitiesList[0].someStringProperty = "123"; //change some other properties here //saving changes to database some time later MyDbContext.SaveGhanges(); MyDbContext.Database.Connection.Close();
但在此解决方案中,数据库连接持续打开时间过长.当UI工作时它不应该打开(因为用户可以在几个小时内更改实体).
2)获得List< MyEntity>之后关闭连接.并打开
将更新传递给数据库时再次连接.所以它会奏效
像这样:
MyDbContext.Database.Connection.open(); List<MyEntity> EntitiesList = MyDbContext.MyEntities.ToList(); MyDbContext.Database.Connection.Close(); //passing EntitiesList to the UI,where user can change them EntitiesList[0].someStringProperty = "123"; //change some other properties here //saving changes to database some time later MyDbContext.Database.Connection.open(); foreach(var entity in EntitiesList) { //Attach updated entity and make context kNow that it is modified MyDbContext.MyEntities.Attach(entity); MyDbContext.MyEntities(entity).State = EntityState.Modified; } MyDbContext.SaveGhanges(); MyDbContext.Database.Connection.Close();
但在这个解决方案中,我认为绝对所有entites的所有属性都被修改了.它导致巨大的数据库更新开销.
另一个选择是编写MyEntityWrapper类,它将跟踪用户执行的所有更改,并知道需要更新哪些属性.所以我可以将上面的代码更改为这个:
foreach(var entity in EntitiesList) { //Attach updated entity and make context kNow which properties are modified MyDbContext.MyEntities.Attach(entity); MyDbContext.Entry(entity).Property(e => e.someStringProperty).IsModified = true; //mark other changed properties }
那么 – 是否有更优雅的解决方案,我是否可以在不编写MyEntityWrapper类的情况下仅更新已更改的属性?我可以简单地告诉DbContext:“这里有一些List< MyEntity> – 接受它,确定哪些属性与数据库中的值不同并更新这些值”?
BTW.如果重要 – 我正在通过Devart dotConnect for sqlite EntityFramework 6.0.1使用sqlite数据库
解决方法
public virtual void Update(T entity,params Expression<Func<T,object>>[] updatedProperties) { //Ensure only modified fields are updated. var dbEntityEntry = DbContext.Entry(entity); if (updatedProperties.Any()) { //update explicitly mentioned properties foreach (var property in updatedProperties) { dbEntityEntry.Property(property).IsModified = true; } } else{ //no items mentioned,so find out the updated entries foreach (var property in dbEntityEntry.OriginalValues.PropertyNames) { var original = dbEntityEntry.OriginalValues.GetValue<object>(property); var current = dbEntityEntry.CurrentValues.GetValue<object>(property); if (original != null && !original.Equals(current)) dbEntityEntry.Property(property).IsModified = true; } } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。