Как правильно обрабатывать не отслеживающие объекты самоконтроля? - PullRequest
4 голосов
/ 22 марта 2010

Самостоятельно отслеживаемые объекты. Высокий.

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

return Db.Users;

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

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

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

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

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

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. Обновление свойств по мере необходимости

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


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

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

1 Ответ

6 голосов
/ 09 июля 2010

сценарий 1

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

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

сценарий 2 Однако, если вы находитесь на сервере, рекомендуется создать метод в частичном классе для objectcontext с именем 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 если пользовательская сущность извлекается из другого контекста, тогда контекст, который вы будете использовать для сохранения, тогда есть еще один вариант, где вы помечаете сущность как измененную и не заботитесь о том, что было изменено.

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 если пользовательская сущность извлекается из другого контекста, тогда контекст, который вы будете использовать для сохранения, тогда есть еще один вариант, когда вы извлекаете исходную сущность.

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 со множеством сценариев.

...