2011-08-16 6 views
12

Mam tabelę użytkowników. istnieją odniesienia do tej tabeli z innych tabel dla pól takich jak CreatedBy.Nie można wstawić duplikatu klucza do obiektu "dbo.User". R nPozdrawienie zostało zakończone.

Problem polega na tym, że wstawiając wiersz innej tabeli (np. "X"), próbuje wstawić nowego użytkownika do tabeli użytkownika.

Co należy zrobić, to wstawić wiersz do tabeli "x" z CreatedBy jako istniejący użytkownik.

Korzystanie z Entity Framework 4. Czy ktoś wcześniej miał takie problemy?

+0

pokrewne pytanie: http://stackoverflow.com/questions/5449724/entity-framework-code-first-cannot-insert-duplicate-key-in-object-db – Stefan

Odpowiedz

31

Możesz wstawić encję razem z powiązanymi podmiotami lub możesz wstawić encję bez powiązanych podmiotów, odwołując się tylko do istniejących. To zależy od kodu, który piszesz.

Przykład 1:

User user = GetUserFromSomewhere(); 
using (var context = new MyContext()) 
{ 
    Order order = new Order(); 
    order.CreatedBy = user; 

    context.Orders.AddObject(order); 
    // will put both order and related entity user into Added state 
    // because user is not attached to the context 

    context.SaveChanges(); 
    // creates new order and new user and sets the relationship between them 
} 

Przykład 2:

using (var context = new MyContext()) 
{ 
    User user = context.Users.SingleOrDefault(u => u.Id == 1); 
    // query attaches this user to this context 
    // user is in state Unchanged now 

    Order order = new Order(); 
    order.CreatedBy = user; 

    context.Orders.AddObject(order); 
    // will put the order into Added state but doesn't touch the 
    // state of already attached related entities -> user remains 
    // in state Unchanged 

    context.SaveChanges(); 
    // creates new order with reference to user, but doesn't create new user 
} 

Przykład 3:

User user = GetUserFromSomewhere(); 
using (var context = new MyContext()) 
{ 
    context.Users.Attach(user); 
    // we attach explicitely to the context telling EF thereby 
    // that we know that this user exists in the DB 
    // user is in state Unchanged now 

    Order order = new Order(); 
    order.CreatedBy = user; 

    context.Orders.AddObject(order); 
    // will put the order into Added state but doesn't touch the 
    // state of already attached related entities -> user remains 
    // in state Unchanged 

    context.SaveChanges(); 
    // creates new order with reference to user, but doesn't create new user 
} 

Edycja

Przykład 4:

int userId = GetUserIdFromSomewhere(); 
using (var context = new MyContext()) 
{ 
    var user = new User { Id = userId }; 
    // we create a stub user entity with the correct primary key 
    // It's not necessary to set other properties 
    // to only set the relationship to the order 

    context.Users.Attach(user); 
    // we attach explicitely to the context telling EF thereby 
    // that we know that this user exists in the DB 
    // user is in state Unchanged now 

    Order order = new Order(); 
    order.CreatedBy = user; 

    context.Orders.AddObject(order); 
    // will put the order into Added state but doesn't touch the 
    // state of already attached related entities -> user remains 
    // in state Unchanged 

    context.SaveChanges(); 
    // creates new order with reference to user, but doesn't create new user 
} 
+0

Doskonała dedukcja mojego problemu. Właśnie, że już robiłem przykład 3. Jedyną różnicą jest to, że zamiast uzyskiwania użytkownika przez GetUserFromSomeWhere(); Przekazywałem obiekt użytkownika jako parametr ... przez przewód WCF ... Więc traciłem kontekst. To powodowało, że Entity Framework również wstawiał obiekt użytkownika. Ponieważ nie wiedział, że już istnieje. Będę musiał wysłać identyfikatory od klienta i uzyskać użytkowników na podstawie identyfikatorów po stronie serwera. Albo musiałbym uwzględnić w modelu klucze obce ... tak, żebym mógł to zrobić ... order.CreatedBy.Id = id; –

+2

@Nilotpal: 'GetUserFromSomeWhere' było jakoś symulacją usługi WCF, lub ogólnie, że twoja jednostka użytkownika została odłączona od kontekstu, w którym dokonujesz modyfikacji. Używanie własności klucza obcego jest generalnie dobrym pomysłem. Alternatywnie możesz również pracować z encją użytkownika "stub" i dołączyć ją do kontekstu: 'var user = new User {Id = userId}; context.Users.Attach (użytkownik); '. W przypadku opcji "Dołącz" ważne jest tylko ustawienie właściwości klucza podstawowego. Pozostałe właściwości mogą pozostać puste, jeśli chcesz tylko ustawić relację z zamówieniem. Zobacz przykład 4 w mojej sekcji Edycja powyżej. – Slauma

+1

@Slauma - +1. Doskonałe przykłady. –

Powiązane problemy