Состояние входа, показывающее разные значения при чтении напрямую и при чтении из переменной - PullRequest
1 голос
/ 21 сентября 2011

Я использую Entity Framework 4.1 и сначала код в asp.net mvc.Просто чтобы проверить обучение, я написал ниже код (контроллер).

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

В приведенном выше коде вы можете видеть, когда я выполняю entry.State его высказывание без изменений, если я делаю db.Entry(person).State его высказывание изменилось.Кто-нибудь может объяснить, почему ??

Ответы [ 2 ]

2 голосов
/ 21 сентября 2011

Если у вас включено автоматическое обнаружение изменений (по умолчанию в EF 4.1) Entry вызывает DetectChanges внутри. Метод начинается, вероятно, примерно так:

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

Во втором вызове db.Entry(person) объект изменился, и метод DetectChanges обнаруживает это, сравнивая снимок, сделанный при загрузке объекта с текущими значениями. Поскольку существует разница, состояние изменяется с Unchanged на Modified.

Также State объекта entry, созданного вами до изменения, перейдет к Modified, поскольку DbEntityEntry.State, скорее всего, свойство, которое просто распространяет значение State внутреннего _internalEntityEntry, которое остается один и тот же экземпляр в обоих DbEntityEntry объектах.

Если вы действительно хотите сохранить прежнее состояние объекта, вам нужно сохранить сам State, а не только объект entry:

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

Это просто перечисление и не изменится при последующем вызове Entry.

Вы можете сравнить это поведение с поведением при отключении автоматического обнаружения изменений:

db.Configuration.AutoDetectChangesEnabled = false;

Обе sb.Append... строки получат состояние Unchanged в этом случае, потому что EF больше не замечает, что одно из ваших свойств POCO изменилось, потому что DetectChanges не вызывается.

1 голос
/ 21 сентября 2011

Я думаю, что метод 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...