2011-12-13 11 views
8

W mojej aplikacji mam następujący kod ...Entity Framework Błąd: Obiekt z wartością null EntityKey nie może być dołączony do kontekstu obiektu

public Boolean SaveUserInformation(UserInfoDTO UserInformation) 
    { 
     return dataManager.SaveUserInfo(new UserInfo() 
     { 
      UserInfoID = UserInformation.UserInfoID.HasValue ? UserInformation.UserInfoID.Value : 0, 
      UserID = UserInformation.UserID, 
      ProxyUsername = UserInformation.ProxyUsername, 
      Email = UserInformation.Email, 
      Status = UserInformation.Status 
     }); 
    } 

Ten kod wywołuje metodę na obiekcie, który wykorzystuje DataManager Entity Framework ...

public Boolean SaveUserInfo(UserInfo userInfo) 
    { 
     try 
     { 
      //Validate data prior to database update 
      if (userInfo.UserID == null) { throw new Exception("UserInfoDomainModel object passed to PriorityOne.Data.DataManager.SaveUserInfo with UserID property set to NULL."); } 
      if (userInfo.ProxyUsername == null) { throw new Exception("UserInfoDomainModel object passed to PriorityOne.Data.DataManager.SaveUserInfo with ProxyUsername property set to NULL."); } 
      if (userInfo.Email == null) { throw new Exception("UserInfoDomainModel object passed to PriorityOne.Data.DataManager.SaveUserInfo with Email property set to NULL."); } 

      if (userInfo.UserInfoID == 0) 
      { 
       //Perform Insert 
       using (PriorityOneEntities entities = new PriorityOneEntities()) 
       { 
        entities.UserInfoes.AddObject(userInfo); 
        entities.SaveChanges(); 
       } 
      } 
      else 
      { 
       //Perform Update 
       using (PriorityOneEntities entities = new PriorityOneEntities()) 
       { 
        entities.Attach(userInfo); 
        entities.SaveChanges(); 
       } 
      } 

      return true; 
     } 
     catch (Exception ex) 
     { 
      //TODO: Log Error 
      return false; 
     } 

    } 

Wkładka tego kodu działa dobrze. Ale kiedy próbuję wykonać aktualizację, otrzymuję komunikat o błędzie: "Obiekt o zerowej wartości EntityKey nie może być dołączony do kontekstu obiektu."

Występuje w tym wierszu kodu: entities.Attach (userInfo);

Staram się uniknąć robienia wycieczek do bazy danych tylko po to, aby wybrać rekord, który później wprowadzę i zaktualizuję, co spowoduje dwie rundy wycieczek do bazy danych.

Jakieś pomysły, co jest nie tak, lub jak mógłbym lepiej to osiągnąć?

Dzięki.

Odpowiedz

20

Wygląda używasz EF 4.1+
Trzeba powiedzieć EF, w jakiej jednostka zostać zaktualizowane (stan Zmodyfikowana):

//Perform Update 
using (PriorityOneEntities entities = new PriorityOneEntities()) 
{ 
    entities.Entry(userInfo).State = EntityState.Modified; 
    entities.SaveChanges(); 
} 

PS: Nie musisz jednoznacznie dzwonić pod numer Attach. Robi się pod maską.

Aktualizacja:
na podstawie komentarzy, używasz EF 4.0. Oto, co trzeba zrobić, aby dołączyć swój obiekt jako zmodyfikowany EF 4.0:

ctx.AddObject("userInfoes", userInfo); 
ctx.ObjectStateManager.ChangeObjectState(userInfo, EntityState.Modified); 
ctx.SaveChanges(); 

Nie można używać Attach metody. Z http://msdn.microsoft.com/en-us/library/bb896271.aspx:

If more than one entity of a particular type has the same key value, the Entity Framework will throw an exception. To avoid getting the exception, use the AddObject method to attach the detached objects and then change the state appropriately.

+0

To była pierwsza rzecz, o której pomyślałem, ale błąd byłby inny. Dobrze? – Shymep

+0

Theerror jest, ponieważ twój podmiot jest w stanie "Dodano". Ale masz podobną jednostkę w bazie danych z tym samym kluczem podstawowym. musisz ręcznie zmienić stan. Testowane i działa poprawnie. – Kamyar

+0

Nie wydaje się, że mam dostęp do metody Entry() na moim obiekcie entity. Czy możesz dać mi trochę więcej wskazówek? – jdavis

3

Od MSDN

The object that is passed to the Attach method must have a valid EntityKey value. If the object does not have a valid EntityKey value, use the AttachTo method to specify the name of the entity set.

Nadzieja to pomoże.

+0

że wykorzystywana metoda AttachTo tak: entities.AttachTo (entities.UserInfoes.EntitySet.Name, userinfo); I to dba o błąd. Nie mam już wyjątku, ale nie widzę zmian w bazie danych. – jdavis

+1

Spróbuj tego [artykułu] (http://geekswithblogs.net/michelotti/archive/2009/11/27/attaching-modified-entities-in-ef-4.aspx). – Shymep

+0

Czy próbowałeś następujące: 'dc.AttachToOrGet (userInfo.EntityKey.EntitySetName, ref userInfo);'? Działa to dobrze dla mnie (gdzie 'dc' jest kontekstem danych). Zwłaszcza, jeśli ten sam obiekt istnieje już gdzie indziej, wówczas otrzymuje oryginalne odwołanie wskazujące na to samo wystąpienie. – Matt

Powiązane problemy