Как правильно обращаться с объектами самоотслеживания без отслеживания?

Самоотслеживающие сущности. Потрясающий.

За исключением случаев, когда вы делаете что-то вроде

return Db.Users;

ни одна из самоотслеживающих сущностей не отслеживается (пока, возможно, они не будут десериализованы).

Отлично. Таким образом, мы должны признать, что существует вероятность того, что объект, возвращающийся к нам, не имеет включенного отслеживания.

Что теперь???

Вещи, которые я пробовал

Для данного тела метода:

using (var db = new Database())
{
    if (update.ChangeTracker.ChangeTrackingEnabled)
        db.Configurations.ApplyChanges(update);
    else
        FigureItOut(update, db);

    db.SaveChanges();
    update.AcceptChanges();
}

Все следующие реализации FigureItOut терпят неудачу:

db.Configurations.Attach(update);
db.DetectChanges();

Ни

db.Configurations.Attach(update);
db.Configurations.ApplyCurrentValues(update);

Ни

db.Configurations.Attach(update);
db.Configurations.ApplyOriginalValues(update);

Ни

db.Configurations.Attach(update);
db.Configurations.ApplyChanges(update

Ни о чем другом, что я могу придумать, кроме как

  1. Получение исходной сущности из базы данных
  2. Сравнение каждого свойства вручную
  3. Обновление свойств по мере необходимости

Что именно я должен делать с объектами самоотслеживания, которые сами себя не отслеживают??


Небольшое обновление:

Слепая маркировка объекта как измененного работает, однако это кажется немного вонючим. Это лучшее, что мы можем сделать в этом случае?


person Community    schedule 22.03.2010    source источник
comment
Эх, кажется, я снова ушел туда, куда, по крайней мере, ходили немногие.   -  person    schedule 23.03.2010


Ответы (1)


сценарий 1

Вот несколько рекомендуемых практик, которым нужно следовать. Когда вы используете STE в сценарии WCF, вы должны полагаться на средство отслеживания изменений, которое реализует STE, поэтому на стороне сервера вы делаете следующее.

db.Users.ApplyChanges(user);
db.SaveChanges();

сценарий 2 Однако, если вы работаете на сервере, рекомендуется создать метод в разделяемом классе для объектного контекста с именем EnableChangeTracking. Метод будет запрашивать объекты, которые находятся в неизмененном состоянии, реализующем IObjectWithChangeTracker и включающем отслеживание изменений, поэтому что-то вроде этого

user = db.users.first(u => u.userid == 1);
db.EnableChangeTracking();

теперь попытайтесь сохранить пользовательский объект из другого контекста, из которого он был первоначально получен.

db2.users.ApplyChanges(user);
db2.SaveChanges();

сценарий 3, если на стороне сервера вы подключены к тому же контексту объекта, из которого вы извлекли объект пользователя, тогда вы используете STE как простой объект poco, как показано ниже.

user = db.users.first(u => u.userid == 1);
user.LastName = "XYZ";
db.DetectChanges(); //no need for it cuz Savechanges implicitly calls this.
db.SaveChanges();

сценарий 4, если пользовательский объект извлекается из другого контекста, тогда контекст u будет использовать его для сохранения, тогда вот еще один вариант, когда вы помечаете объект как измененный и не заботитесь о том, что было изменено.

user = db.users.first(u => u.userid == 1);
var db2 = new ObjectContext();
user.LastName = "XYZ";
db2.Users.Attach(user);
// i prefer this option..
db2.ObjectStateManager.ChangeObjectState(user,EntityState.Modified); 
db2.SaveChanges(); // updates all columns

сценарий 5, если пользовательский объект извлекается из другого контекста, тогда контекст u будет использовать его для сохранения, тогда вот еще один вариант, когда u извлекает исходный объект.

user = db.users.first(u => u.userid == 1);
user.lastName ="XYZ";
var db2 = new ObjectContext();
db2.Users.First(u => u.userid == user.userid);
db2.users.ApplyCurrentValues(user);
db2.SaveChanges();

Вот сообщение в блоге, в котором описывается несколько сценариев. http://weblogs.asp.net/zeeshanhirani/archive/2010/03/30/modifying-self-tracking-entity-on-the-server.aspx

Я подробно описываю эти концепции в своей книге рецептов Entity Framework 4.0 с множеством сценариев.

person zeeshanhirani    schedule 09.07.2010