как лучше всего прикрепить объект сущности, который отделен от anthoer ObjectContext?

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

У меня просто такой случай: я получаю объект сущности из одного 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);

ИЛИ

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» в приведенном выше коде.

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

Огромное спасибо.


person Jeff Chen    schedule 07.02.2011    source источник


Ответы (1)


Я не понимаю ваш первый пример. Почему вы сначала получаете сущность от 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) должен сначала запросить БД, чтобы получить старые значения.

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

person Ladislav Mrnka    schedule 07.02.2011
comment
Привет Ладислан, спасибо за ваш ответ. Но будет ли ваше первое исключение для кода говорить, например, что «ObjectContext не может иметь два объекта сущностей с одним и тем же EntityKey»? Я всегда получаю это исключение, когда просто напрямую присоединяю объект к новому экземпляру ObjectContext. - person Jeff Chen; 08.02.2011