C# 对同一域/实体模型的两个引用
问题 我想保存在用户编辑时已更改的模型属性。这是我想做的C# 对同一域/实体模型的两个引用,c#,.net,sql-server,asp.net-mvc,entity-framework,C#,.net,Sql Server,Asp.net Mvc,Entity Framework,问题 我想保存在用户编辑时已更改的模型属性。这是我想做的 检索编辑的视图模型 获取域模型并映射回更新的值 在存储库上调用update方法 获取“旧”域模型并比较字段的值 将更改后的值(JSON)存储到表中 但是,我在第4步中遇到了问题。实体框架似乎不想再次访问数据库以获取具有旧值的模型。它只返回我拥有的相同实体 尝试的解决方案 我尝试过使用Find()和SingleOrDefault()方法,但它们只是返回我当前拥有的模型 示例代码 private string ArchiveChanges(T
Find()
和SingleOrDefault()
方法,但它们只是返回我当前拥有的模型
示例代码
private string ArchiveChanges(T updatedEntity)
{
//Here is the problem!
//oldEntity is the same as updatedEntity
T oldEntity = DbSet.SingleOrDefault(x => x.ID == updatedEntity.ID);
Dictionary<string, object> changed = new Dictionary<string, object>();
foreach (var propertyInfo in typeof(T).GetProperties())
{
var property = typeof(T).GetProperty(propertyInfo.Name);
//Get the old value and the new value from the models
var newValue = property.GetValue(updatedEntity, null);
var oldValue = property.GetValue(oldEntity, null);
//Check to see if the values are equal
if (!object.Equals(newValue, oldValue))
{
//Values have changed ... log it
changed.Add(propertyInfo.Name, newValue);
}
}
var ser = new System.Web.Script.Serialization.JavaScriptSerializer();
return ser.Serialize(changed);
}
public override void Update(T entityToUpdate)
{
//Do something with this
string json = ArchiveChanges(entityToUpdate);
entityToUpdate.AuditInfo.Updated = DateTime.Now;
entityToUpdate.AuditInfo.UpdatedBy = Thread.CurrentPrincipal.Identity.Name;
base.Update(entityToUpdate);
}
private string ArchiveChanges(T updatedEntity)
{
//问题就在这里!
//oldEntity与UpdateEntity相同
T oldEntity=DbSet.SingleOrDefault(x=>x.ID==updatedEntity.ID);
字典已更改=新字典();
foreach(typeof(T).GetProperties()中的var propertyInfo)
{
var property=typeof(T).GetProperty(propertyInfo.Name);
//从模型中获取旧值和新值
var newValue=property.GetValue(updatedEntity,null);
var oldValue=property.GetValue(oldEntity,null);
//检查这些值是否相等
如果(!object.Equals(newValue,oldValue))
{
//值已更改…请记录它
添加(propertyInfo.Name,newValue);
}
}
var ser=new System.Web.Script.Serialization.JavaScriptSerializer();
返回序列序列化(已更改);
}
公共覆盖无效更新(T entityToUpdate)
{
//用这个做点什么
字符串json=ArchiveChanges(entityToUpdate);
entityToUpdate.AuditInfo.Updated=DateTime.Now;
entityToUpdate.AuditInfo.UpdatedBy=Thread.CurrentPrincipal.Identity.Name;
基本更新(entityToUpdate);
}
问题在于实体框架缓存在DbSet中读取的对象。因此,当您第二次请求该对象时,它不会进入数据库,因为它已经加载了该对象
然而,好消息是实体自动跟踪原始值。有关如何获取它们的信息,请参见此问题:更新报告后是否有此代码?从你的步子上看,听起来就是这样。如果是的话,那么你会得到新的模型;您更新了旧模型。如果要执行此操作,需要在更新之前获取旧模型。@Tyrsius no its BEFORE。我添加了调用方法以获得更清晰的图片。您正在处理/更新的实体已附加到上下文(已跟踪)。这意味着如果您修改它,它将进入修改状态(这意味着当调用SaveChanges时,它将在DB中进行更新)。但是,当仅查询实体(SingleOrDefault调用)时,由于实体附加到上下文(内存缓存中),它将直接从上下文中检索,并且不会往返到DB。如果要从DB中检索实体,则需要将其从当前上下文中分离(然后重新附加该实体,以便对SaveChanges的调用将实际更新DB)。