我有一个模型,我们可以调用Person
// My table tb_person
public class Person
{
public int Id {get;set;}
public string Name {get; set;}
public int Age {get; set;}
public DateTime AddTime {get; set;}
public DateTime UPdateTime {get;set;}
public string Remark {get; set}
public bool IsEnable {get;set;}
}
首先我得到了Mdoel
using (var ctx = new MyEntitys())
{
ctx.Configuration.ProxyCreationEnabled = false;
ctx.Configuration.LazyLoadingEnabled = false;
Person firstModel = ctx.Persons.Where( x=> x.Id = 5).FirstOrDefault();
}
现在很长一段时间我需要修改模型,但我需要在数据库中获取旧模型并进行比较。
using (var ctx = new MyEntitys())
{
ctx.Configuration.ProxyCreationEnabled = false;
ctx.Configuration.LazyLoadingEnabled = false;
Person CurrentModel = ctx.Persons.Where( x=> x.Id = 5).FirstOrDefault();
// Just a example for judge or compare
if (CurrentModel.IsEnable)
{
if (CurrentModel.UpdateTime != null)
{
firstModel.Update = time;
}
}
else
{
firstModel.AddTime = new DateTime();
}
ctx.Entry(firstModel).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
}
然后它将抛出:
为什么我不使用CurrentModel
进行更新?由于firstModel
我更改了这么多属性,我不想复制所有属性。我只需要从数据库中获取一些信息,然后将其替换为Save。
那样我不喜欢它。我感到困惑,而且很复杂。
我也尝试用另一种方法来修复它:
//只是在没有得到它的情况下判断它
if (ctx.Persons.Any( x=> x.Id = 5 && x.UpdateTime != null){
// then do something change after judge
}
基本上现在我知道问题来源:实体框架在获取后缓存结果。这就是为什么在我得到一个新模型之后,它不允许我使用旧模型。
但我仍在寻找一种更好的高度表现方式(我只想减少与数据库的交易)来修复它。 你有什么想法吗?
答案 0 :(得分:1)
当您使用Entry()
获取对象的条目时,上下文检查上下文中是否存在该对象引用的条目然后返回它,如果该对象引用没有条目,则它添加一个该对象进入上下文。
当您创建var p1= new Person()
和var p2=new Person()
时,p1和p2不一样,即使它们的所有属性相同,它们也有不同的引用。
在您的情况下,修改后的实体(第一个)和原始实体是不同的实例,因此上下文尝试首先创建一个条目,因为您已将原始版本加载到上下文中,将抛出Object with the same key already exists
的异常。
要了解您可以做什么,请考虑以下情况:
情景1
在这种情况下,您从上下文中获取一个人并将其传递给客户端,然后客户端将修改后的版本发送给您以放入数据库,并且您还要检查某人的原始版本,然后更新数据库。 你应该这样做:
//get original version
original= context.Persons.Where( x=> x.Id = modified.Id ).FirstOrDefault();
//do comparison and what you want to do
//but only apply changes to modified version
if (original.Age > 20)
modified.SomeProperty=SomeValue;
//save modified version
context.Entry(original).CurrentValues.SetValues(modified);
context.SaveChanges();
这种方式类似于以前版本ApplyCurrentValues
中ObjectContext
的{{1}}方法
场景2
在这种情况下,您从上下文中获取一个人并将其传递给客户端,然后客户端将修改后的版本发送给您,而您(无需检查原始版本)将其放入数据库中。
你应该这样做:
Entity Framework
并且没有必要找到原件。
更多信息: