Какова лучшая практика, чтобы прикрепить объект сущности, который отделен от anthoer ObjectContext? - PullRequest
0 голосов
/ 07 февраля 2011

Как указано в заголовке, сколько методов доступно?

У меня просто есть такой случай: я получаю объект сущности из одного ObjectContext, а затем отсоединяю объект сущности от объекта OjbectContext и возвращаю его.

Позже, если я внесу некоторые изменения в этот объект и захочу сохранить изменения обратно в базу данных. Я думаю, что я должен написать так, верно? (Ну, это работает для меня.)

public Url GetOneUrl()
{
    Url u;
    using(ServicesEntities ctx = new ServicesEntities())
    {
        u = (from t in ctx.Urls select t).FirstOrDefault<Url>();
        ctx.Detach(u);
    }
    return u;
}

public void SaveToDB(Url url)
{
   using(ServicesEntities ctx = new ServicesEntities())
   {
       var t = ctx.GetObjectByKey(_Url.EntityKey) as Url;
       ctx.Detach(t);
       ctx.Attach(url);
       ctx.ObjectStateManager.ChangeObjectState(url, System.Data.EntityState.Modified);
       ctx.SaveChanges();
   }
}

Url url = GetOneUrl();
url.UrsString = "http://google.com"; //I just change the content.
SaveToDB(url);

OR

public void SaveToDB(Url url)
{
    using(ServicesEntities ctx = new ServicesEntities())
    {
        var t = ctx.GetObjectByKey(_Url.EntityKey) as Url;
        t = url; //this will make t.UrlString becomes "http://google.com"
        ctx.ApplyCurrentValues<Url>("Urls", t);
        ctx.SaveChanges();
    }
}

Этот способ также работает для меня.

Первый способ - создание оператора sql для обновления всех столбцов таблицы Url, а второй - сценарий sql для обновления только столбцов «UrlString».

Им обоим нужно будет извлечь временный объектный объект из базы данных, который в коде выше обозначен буквой 't'.

Существуют ли другие способы достижения этой цели? Или другой лучший метод вы знаете об этом? Или какое-нибудь официальное решение по этой теме?

Большое спасибо.

1 Ответ

0 голосов
/ 07 февраля 2011

Я не понимаю ваш первый пример. Почему вы впервые получаете сущность от ObjectContext? Это не нужно, потому что вы только что создали новый экземпляр контекста. Вы можете просто использовать:

public void SaveToDB(Url url)
{
   using(ServicesEntities ctx = new ServicesEntities())
   {
       ctx.Attach(url);
       ctx.ObjectStateManager.ChangeObjectState(url, System.Data.EntityState.Modified);
       ctx.SaveChanges();
   }
}

Во втором примере вы можете просто позвонить:

public void SaveToDB(Url url) 
{     
  using(ServicesEntities ctx = new ServicesEntities())     
  {         
     var t = ctx.GetObjectByKey(_Url.EntityKey) as Url; // Ensures that old values are loaded
     ctx.ApplyCurrentValues<Url>("Urls", url);         
     ctx.SaveChanges();     
  } 
} 

Теперь разница между двумя подходами очевидна. Первый подход (Attach) не требует сначала запрашивать БД. Второй подход (ApplyCurrentValues) должен сначала выполнить запрос к БД, чтобы получить старые значения.

Вы можете использовать два дополнительных подхода. Первый - это просто продолжение вашего прежнего подхода. Это позволяет вам определить, какие свойства были изменены. Второй подход - ручная синхронизация с загруженным объектом. Этот подход не использует никаких специальных методов. Вы просто установите свойства загруженного объекта в требуемые значения вручную. Этот подход полезен, если вы работаете с графом объектов вместо одного объекта, поскольку EF не может автоматически синхронизировать изменения в отношениях.

...