Właściwość zależna w ReferentialConstraint jest mapowana na kolumnę wygenerowaną przez sklep

98

Otrzymuję ten błąd podczas zapisu do bazy danych:

Właściwość zależna w ReferentialConstraint jest mapowana na kolumnę wygenerowaną przez sklep. Kolumna: „PaymentId”.

public bool PayForItem(int terminalId, double paymentAmount, 
      eNums.MasterCategoryEnum  mastercategoryEnum, int CategoryId, int CategoryItemId)
    {

        using (var dbEntities = new DatabaseAccess.Schema.EntityModel())
        {
            int pinnumber = 0;
            long pinid = 1; //getPinId(terminalId,ref pinnumber) ;
            var payment = new DatabaseAccess.Schema.Payment();
            payment.CategoryId = CategoryId;
            payment.ItemCategoryId = CategoryItemId;
            payment.PaymentAmount = (decimal)paymentAmount;
            payment.TerminalId = terminalId;
            payment.PinId = pinid;

            payment.HSBCResponseCode = "";
            payment.DateActivated = DateTime.Now;
            payment.PaymentString = "Payment";
            payment.PromotionalOfferId = 1;
            payment.PaymentStatusId = (int)eNums.PaymentStatus.Paid;

            //payment.PaymentId = 1;

            dbEntities.AddToPayments(payment);
            dbEntities.SaveChanges();
        }
        return true;
    }

Schemat to:

wprowadź opis obrazu tutaj

Walijski król
źródło

Odpowiedzi:

180

Czy to możliwe, że zdefiniowałeś złą relację między kolumnami między tabelami? różne kolumny, a jedna została ustawiona jako autonumeryczna.

To mi się przydarzyło.

ju4nj3
źródło
55
Przez pomyłkę nadałem jednemu z moich kluczy obcych Identity (automatyczna inkrementacja). To jest błąd, który otrzymałem.
żartobliwy
3
No! Pozostawiłem część relacji z kluczem obcym jako domyślną podaną przez SQL Server 2008 Management Studio, która była polami klucza podstawowego tabeli podrzędnej, a nie kolumną, którą utworzyłem, aby zawierała wartość klucza obcego.
robaker
12
Jeśli sprawdzisz wyjątek w oknie Quick Watch (tj. (e as System.Data.Entity.Infrastructure.DbUpdateException).Entries), Możesz zobaczyć, która tabela zawiera klucz podstawowy, do którego się odwołujesz.
Cᴏʀʏ
17
Czy nie byłoby fajnie, gdyby komunikaty o błędach EF po prostu określały, na czym polega problem, zamiast wypluć gobbledy-gook?
AR
Użyłem tego zapytania, aby wyświetlić wszystkie relacje w jednym widoku stackoverflow.com/questions/8094156/ ...
Dave
47

Ten błąd mówi, że używasz nieobsługiwanej relacji lub masz błąd w mapowaniu. Twój kod najprawdopodobniej nie ma żadnego związku z błędem.

Błąd oznacza, że ​​istnieje relacja między jednostkami, w których właściwość klucza obcego w jednostce zależnej jest zdefiniowana jako wygenerowana w magazynie. Właściwości wygenerowane przez sklep są wypełniane w bazie danych. EF nie obsługuje właściwości wygenerowanych przez magazyn jako kluczy obcych (a także obliczonych właściwości w kluczach podstawowych).

Ladislav Mrnka
źródło
2
mogę dodać wiersz na serwerze sql z tymi samymi informacjami. kiedy mówisz „Wygenerowano przez sklep”, czy możesz podać przykład?
Welsh King
1
EF to nie SQL Server. Ma swoje ograniczenia. Po prostu znajdź, gdzie używasz dowolnej właściwości FK wygenerowanej przez DB o nazwie PaymentIDi zajmij się nią.
Ladislav Mrnka
ok, mamy tabelę paymenthistory, która ma paymentId jako klucz obcy, czy muszę tam dodać wiersz?
Welsh King
Nie chodzi o dodanie wiersza, ale o definicję kolumny. Jak ustawić tę kolumnę?
Ladislav Mrnka
właśnie kliknąłem model relacji w Visual Studio i otrzymuję Nazwę „Płatność” nie można użyć w typie „Płatność”. nazwy elementów członkowskich nie mogą być takie same, jak ich typ obejmujący. Wszelkie pomysły
Welsh King
8

Miałem ten sam problem. Na podstawie udzielonych tutaj odpowiedzi udało mi się go wyśledzić i rozwiązać, ale miałem dziwny problem opisany poniżej - może to komuś pomóc w przyszłości.

W moich tabelach zależnych kolumny klucza obcego zostały ustawione na StoreGeneratedPattern = "Identity". Musiałem zmienić to na „Brak”. Niestety, wykonanie tego wewnątrz projektanta w ogóle nie działało.

Zajrzałem do wygenerowanego przez projektanta XML (SSDL) i te właściwości nadal tam były, więc usunąłem je ręcznie. Musiałem też naprawić kolumny w bazie danych (usunąć Identity (1,1) z CREATE TABLE SQL)

Potem problem zniknął.

surfować
źródło
Dzięki za tę wskazówkę. Zmiana pola w projektancie z Identity na None zmieniła to w jednym miejscu w EDMX, ale nie w innym miejscu, więc nadal otrzymywałem błąd, dopóki sam nie wyedytowałem pliku EDMX. Niestety EntityFramework następnie zwariował i próbował ponownie wstawić powiązane encje w innych tabelach, ale nadal było to pomocne w obejściu tego komunikatu o błędzie.
FTWinston
6

Miałem ten sam problem i po pewnym zagłębieniu się w projekt tabeli na serwerze sql stwierdziłem, że omyłkowo ustawiłem klucz podstawowy tabeli również jako klucz obcy.

sql server projektowania tabel

Na tym obrazku widać, że JobID jest kluczem podstawowym tabeli, ale także błędnie kluczem obcym.

Manish Bhakuni
źródło
2

Mój problem był spowodowany nadmiarowym zdefiniowaniem klucza podstawowego w konfiguracji.

this
   .Property(p => p.Id)
   .HasColumnName(@"id")
   .IsRequired()
   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) // this is redundant when you want to configure a One-to-Zero-or-One relationship
   .HasColumnType("int");

Usuń tę linię

.HasDatabaseGeneratedOption (DatabaseGeneratedOption.Identity)


Przykład http://www.entityframeworktutorial.net/code-first/configure-one-to-one-relationship-in-code-first.aspx

To wystarczy, aby zdefiniować związek

// Configure Student & StudentAddress entity
modelBuilder.Entity<Student>()
            .HasOptional(s => s.Address) // Mark Address property optional in Student entity
            .WithRequired(ad => ad.Student); // mark Student property as required in StudentAddress entity. Cannot save StudentAddress without Student
Piotr
źródło
1

Ponownie sprawdź związek między płatnością a innymi tabelami / podmiotami. W tym te, które nie powinny zawierać PaymentId, ponieważ tam najprawdopodobniej ukrywa się problem.

Podczas tworzenia kluczy obcych w SQL Server Management Studio klucz podstawowy jest domyślny i ten domyślny jest przywracany po zmianie tabeli nadrzędnej, dlatego należy uważać, aby zmienić wartości we właściwej kolejności w oknie „Tabele i kolumny”.

Ponadto po naprawieniu problematycznej relacji istnieje duża szansa, że ​​zwykłe „Odśwież” w modelu nie usunie poprawnie błędnej relacji z modelu i wystąpi ten sam błąd nawet po „ naprawieniu ”, więc zrób to sam w modelu przed wykonaniem odświeżenia. (Przekonałem się o tym na własnej skórze.)

znak
źródło
1

Jeśli sprawdziłeś swoje relacje i jesteś tam dobry.

Usuń tabelę w edmx, a następnie zaktualizuj z bazy danych. Pozwoli to zaoszczędzić na ręcznej aktualizacji.

rickjr82
źródło
Naprawdę dziękuję za twoją radę, spędziłem godzinę na sprawdzeniu mojej bazy danych, ale po usunięciu, a następnie zaktualizowaniu wszystko jest w porządku.
Tấn Nguyên
1

Dla mnie był to źle umieszczony klucz obcy w tabeli, ale nawet po przeróbce tabeli, aby go naprawić, nadal nie działał. Musisz zaktualizować pliki EDMX (a nie wystarczy „odświeżyć” tabelę z modelu, musisz usunąć i ponownie dodać tabelę w modelu).

knocte
źródło
1

Oprócz zaakceptowanej odpowiedzi, jeśli używasz generatora EF Reverse POCO lub innego narzędzia, które generuje twoje POCO, upewnij się, że je regenerujesz !

adam0101
źródło
Nigdy, przenigdy nie zapominaj o ponownym uruchomieniu niestandardowego narzędzia T4 (trzymając POCO) po zmodyfikowaniu zewnętrznego generatora modelu EF w pierwszej kolejności DB (przechowującego konteksty) ... NIGDY! XD (równie dobrze mógł oszaleć -.- ')
Shockwaver
0

W moim przypadku problem wynikał z dwukierunkowej relacji 1-1:

class Foo{
[Key]
Id
[ForeignKey]
BarId
...
}
class Bar{
[Key]
Id
[ForeignKey]
FooId
...
}

Musiałem po prostu usunąć jeden z dwóch kluczy obcych (zresztą nie jest to konieczne).

wecky
źródło
0

W moim przypadku po prostu nie miałem poprawnie ustawionych uprawnień do bazy danych. Miałem tylko do odczytu zestaw, a struktura Entity dawała mi błąd ReferentialConstraint, który mnie wyrzucił. Dodano dodatkowe uprawnienia do zapisu i wszystko było dobrze.

Mdhattr
źródło
0

W moim przypadku miałem właściwość wygenerowaną w bazie danych i właściwość nawigacji ForeignKey skonfigurowaną tak, aby odwoływała się do powiązanej tabeli 1 do 1.

Nie było to coś, co mogłem usunąć, musiałem mieć możliwość ustawienia klucza podstawowego jednostki jako generowanej w bazie danych ORAZ musiałem mieć możliwość odniesienia się do tabeli 1 do 1 jako właściwości nawigacji.

Nie jestem pewien, czy to jest to samo dla innych, ale ten problem pojawiał się tylko podczas tworzenia nowej encji, czytanie lub edytowanie istniejących jednostek nie wykazywało problemu, więc obejrzałem ten problem, tworząc odziedziczoną wersję mojego kontekstu i używając metoda Fluent, aby wyłączyć właściwość nawigacji podczas tworzenia.

Tak więc mój pierwotny byt wyglądał tak:

public partial class MyEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid id{ get; set; }


    // Navigation
    [ForeignKey("id")]
    public PathEntity Path { get; set; }
}

Stworzyłem więc specjalny dziedziczony kontekst, który wyglądał następująco:

    private class _navPropInhibitingContext : EF.ApplicationDBContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<MyEntity>()
                .Ignore(e => e.Path);

        }
    }

a następnie zmienił kod, który utworzył nową jednostkę, aby użytkownik miał nowy typ kontekstu

    using (var specialContext = new _navPropInhibitingContext())
    {
        var dbModel = new MyEntity() 
        {
            ...
        };

        specialContext.MyEntity.Add(dbModel);
        await specialContext.SaveChangesAsync();
    }

Mam nadzieję, że to komuś pomoże

Chris Terry
źródło
0

W moim przypadku pole Id, którego FK jest tylko w Entity Framework, właściwość „StoreGeneratedPattern” została ustawiona na „Itentity” zamiast „None”

Lew K.
źródło