1

我在asp.net mvc中使用实体框架4.1和代码。只是为了测试学习我写下面的代码(一个控制器)。直接读取和从变量读取时显示不同值的条目状态

public ActionResult Foo() 
{ 
    StringBuilder sb = new StringBuilder(); 
      using (var db = new DemoDataBase1Context()) 
      { 
       //get person from db 
       var person = db.Persons.FirstOrDefault(); 

       //get entry 
       var entry = db.Entry(person); 

       //now change the person object 
       person.Name = "Some New Value"; 

       //print entity state 

       //this is showing unchanged 
       sb.Append("<br>State: " + entry.State); 

       //this is showing changed 
       sb.Append("<br>State: " + db.Entry(person).State);     
      } 

    return Content(sb.ToString()); 
} 

在上面的代码中,你可以看到,当IAM做entry.State其说法不变,如果我这样做db.Entry(person).State其说法改变。任何人都可以解释为什么?

回答

2

如果启用自动变化检测(这是EF 4.1默认)Entry内部调用DetectChanges。该方法开始可能与此类似:

if (Configuration.AutoDetectChangesEnabled) 
    ChangeTracker.DetectChanges(); 
//... 

在对象已经改变的db.Entry(person)你的第二个电话和DetectChanges方法通过比较,当你加载当前值的实体,被做了快照检测这一点。由于状态从UnchangedModified有所不同。

而且你已经创建前的变化会去Modified因为DbEntityEntry.Stateentry对象的State很可能刚刚传播内_internalEntityEntry这仍然是在这两个DbEntityEntry对象相同的实例的State值的属性。

如果你真的想保存一个实体的前国家则需要将State自我拯救,不仅entry对象:

var state = db.Entry(person).State; 

这仅仅是一个枚举,不会与后面的改变致电Entry

你可以当你禁用自动变化检测与行为比较这行为:

db.Configuration.AutoDetectChangesEnabled = false; 

两个sb.Append...线将接收在这种情况下,国家Unchanged因为EF没有现在注意到了你的POCO之一属性已更改,因为不调用DetectChanges

1

我认为Entry方法为您提供当您调用Entry时的对象状态。我不认为这与从变量读取它直接调用它有关。

当您获得对第一个条目的引用时,您的对象不会更改。下一行你改变它并再次调用Entry,此时它被改变。如果您存储到一个参考然后比较这两个我猜他们是不同的引用:

var person = db.Persons.FirstOrDefault(); 

// get reference to entry - unchanged at this point 
var entry1 = db.Entry(person); 

// make a change to the object 
person.Name = "Changed"; 

// get reference to entry - changed now 
var entry2 = db.Entry(person); 

// these will not be equal: probably false 
var equalOrNot = entry1 == entry2; 
+0

我刚刚检查:此语句后'var entry2 = db.Entry(person);'| 'entry1.State'和'entry2.State',现在都说修改。现在我只是注释了'var entry2 = db.Entry(person);','entry1.State'显示Modified。我不知道为什么会发生。 –

+0

更新您的代码以显示您在做什么。当我运行我的测试时,它按预期工作。 – Dismissile