gpt4 book ai didi

c# - 如何仅将实体的已更改属性更新到 Entity Framework

转载 作者:行者123 更新时间:2023-11-30 12:39:32 25 4
gpt4 key购买 nike

假设我们有一个 MyDbContextDbSet<MyEntity>在里面。我正在尝试实现以下场景(因为我发现它被称为断开连接场景或断开连接模式):

  1. 我获得了List<MyEntity>来自数据库(它可以是通过 DbContext.MyEntities.ToList() 的所有记录或通过某些过滤条件的记录 - 这无关紧要)。
  2. 然后将这些实体传递给用户可以更改属性的某些 UI。他的行为是不可预测的:他可以更改每个实体的所有属性,或者他只能更改单个实体的一个属性(他甚至可以根本不执行任何更改)。
  3. 之后,我需要将更新传递给数据库。

为实现该场景,我找到了两种可能的解决方案:

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();

但在这个解决方案中,我认为绝对所有实体的所有属性都被修改了。这会导致巨大的数据库更新开销。

另一个选择是写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类(class)?我可以简单地告诉 DbContext:“这里有一些 List<MyEntity> - 接受它,确定哪些属性与数据库中的值不同并更新这些值”?

顺便说一句。如果重要 - 我正在通过 Devart dotConnect for SQLite + EntityFramework 6.0.1

使用 SQLite 数据库

最佳答案

请看下面的代码,我认为它可能对您有所帮助(在 Google 上找到)

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;
}
}
}

关于c# - 如何仅将实体的已更改属性更新到 Entity Framework ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45294693/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com