
#entityframework #csharp #dotnet #programowanie #pytanie
To już dzisiaj moje drugie pytanie do ef ale tym razem już sam sobie nie odpowiem ( ͡° ͜ʖ ͡°).
Mam takie kod który dodaje record do bazy (ef w trybie disconnected):
Wyjaśnienie: Order zawiera referencje do Customer i listy ProductOrder. Część pogrubioną (petla foreach) sobie darujmy bo tu jest ok. Dodaje do kontekstu (przez Attach) order.Customer bo nie chcę żeby Customer był dodany do bazy jako nowy record - ma to byc referencja do istniejącego recordu.
Problem jest taki, że wywala mi takie błąd na metodzie SaveChanges() :
Czyli próbuje dodać Customer jako nowy record. Dlaczego?
Żeby było śmieszniej to gdy puszcze powyższy kod dwa razy to za drugim razem już zapisze tak jak ma być:
Czego tylko za pierwszym podejściem próbuje zrobić inserta na Customer a za drugim już zapisuje normalnie?
To już dzisiaj moje drugie pytanie do ef ale tym razem już sam sobie nie odpowiem ( ͡° ͜ʖ ͡°).
Mam takie kod który dodaje record do bazy (ef w trybie disconnected):
using (var context = new StoreDbContext())
{
using (var transaction = context.Database.BeginTransaction())
{
try
{
context.Customers.Attach(order.Customer);
foreach (var productOrder in order.Products)
{
context.Products.Attach(productOrder.Product);
context.ProductOrders.Add(productOrder);
}
context.Orders.Add(order);
context.SaveChanges();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
throw ex;
}
}
}Wyjaśnienie: Order zawiera referencje do Customer i listy ProductOrder. Część pogrubioną (petla foreach) sobie darujmy bo tu jest ok. Dodaje do kontekstu (przez Attach) order.Customer bo nie chcę żeby Customer był dodany do bazy jako nowy record - ma to byc referencja do istniejącego recordu.
Problem jest taki, że wywala mi takie błąd na metodzie SaveChanges() :
Cannot insert duplicate key row in object 'dbo.Customers' with unique index 'IX_Name'. The duplicate key value is (Customer1). The statement has been terminated.
Czyli próbuje dodać Customer jako nowy record. Dlaczego?
Żeby było śmieszniej to gdy puszcze powyższy kod dwa razy to za drugim razem już zapisze tak jak ma być:
for (int i = 0; i < 2; ++i)
{
using (var context = new StoreDbContext())
{
using (var transaction = context.Database.BeginTransaction())
{
try
{
context.Customers.Attach(order.Customer);
foreach (var productOrder in order.Products)
{
context.Products.Attach(productOrder.Product);
context.ProductOrders.Add(productOrder);
}
context.Orders.Add(order);
context.SaveChanges();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
continue;
throw ex;
}
}
}
}Czego tylko za pierwszym podejściem próbuje zrobić inserta na Customer a za drugim już zapisuje normalnie?
- Najlepsze
- Wszystkie komentarze







public virtual Customer Customer;masz teżpublic int CustomerId. Jeśli tak jest to przy dodawaniu do contextu nowego Order w polu Customer daj nulla, przypisz CustomerId (które przecież znasz).kombinujesz jak koń pod górkę. Nie wspomne już o tym, ze pomimo jakis 4 lat doswiadczenia z EF nie spotkalem sie ze sformuowaniem "ef disconnected". wtf?
Masz encje A ktora posiada Encje B czy tam wiele encji, masz klucze do nich, czy też pola wirtualne, dodajesz do danej kolekcji (lub przypsiujesz dane cale pole virtualne, albo samo id) a nie robisz jakies atache i inne
Faktycznie teraz chodzi elegancko. Teraz wiem, że wszystkie referencje powinny mieć zdefiniowany też klucz bo bez klucza trzeba się bawić w takie dołanczanie do konktekstu
Pierwszy kawałek kodu:
Komentarz usunięty przez autora