Una proprietà dipendente in un ReferentialConstraint viene mappata a una colonna generata dal negozio


98

Ottengo questo errore durante la scrittura nel database:

Una proprietà dipendente in un ReferentialConstraint viene mappata a una colonna generata dal negozio. Colonna: "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;
    }

Lo schema è:

inserisci qui la descrizione dell'immagine

Risposte:


180

È possibile che tu abbia definito una cattiva relazione di colonna tra le tue tabelle? colonne diverse e una è stata impostata come automatica.

È successo a me.


55
Ho erroneamente reso una delle mie chiavi esterne un'identità (incremento automatico). Questo è l'errore che ho ricevuto.
jocull

3
Doh! Avevo lasciato la parte della chiave esterna della relazione come predefinita fornita da SQL Server 2008 Management Studio, che erano i campi della chiave primaria della tabella figlia, non la colonna che avevo creato per contenere il valore della chiave esterna.
rapinatore

12
Se si ispeziona l'eccezione nella finestra Quick Watch (cioè (e as System.Data.Entity.Infrastructure.DbUpdateException).Entries), è possibile vedere quale tabella contiene la chiave primaria a cui si fa riferimento.
Cᴏʀʏ

17
Non sarebbe bello se i messaggi di errore EF indicassero semplicemente qual era il problema invece di sputare fuori un gobbledy-gook?
AR

Ho usato questa query per visualizzare tutte le relazioni in una vista stackoverflow.com/questions/8094156/…
Dave

47

Questo errore indica che stai utilizzando una relazione non supportata o che hai un errore nella mappatura. Il tuo codice è molto probabilmente assolutamente non correlato all'errore.

L'errore indica che hai una relazione tra entità in cui la proprietà della chiave esterna nell'entità dipendente è definita come generata dal negozio. Le proprietà generate dal negozio vengono inserite nel database. EF non supporta le proprietà generate dall'archivio come chiavi esterne (nonché le proprietà calcolate nelle chiavi primarie).


2
posso aggiungere la riga nel server sql con le stesse informazioni. quando dici Generato in negozio, puoi fare un esempio?
Welsh King,

1
EF non è SQL Server. Ha i suoi limiti. Trova semplicemente dove usi qualsiasi proprietà FK generata da DB chiamata PaymentIDe gestiscila.
Ladislav Mrnka

ok abbiamo una tabella di cronologia pagamenti che ha paymentId come chiave esterna, devo aggiungere una riga lì?
Re gallese

Non si tratta di aggiungere una riga ma di definire la colonna. Come si imposta quella colonna?
Ladislav Mrnka

ho appena fatto clic sul modello di relazione in Visual Studio e sto ottenendo il nome "Pagamento" non può essere utilizzato nel tipo "Pagamento". i nomi dei membri non possono essere uguali al loro tipo di inclusione. Qualsiasi idea
Re gallese

8

Ho avuto lo stesso problema. Sulla base delle risposte fornite qui sono stato in grado di rintracciarlo e risolverlo, ma ho riscontrato uno strano problema descritto di seguito: potrebbe aiutare qualcuno in futuro.

Sulle mie tabelle dipendenti, le colonne chiave esterne sono state impostate su StoreGeneratedPattern = "Identity". Ho dovuto cambiarlo in "Nessuno". Sfortunatamente, farlo all'interno del designer non ha funzionato affatto.

Ho cercato nell'XML generato dal designer (SSDL) e queste proprietà erano ancora lì, quindi le ho rimosse manualmente. Ho anche dovuto correggere le colonne sul database (rimuovere l'identità (1,1) da CREATE TABLE SQL)

Dopo di che, il problema è andato via.


Grazie per questo suggerimento. La modifica del campo nel designer da Identità a Nessuno ha cambiato questo in un punto nell'EDMX, ma non nell'altro, quindi ho ancora ricevuto l'errore finché non ho modificato il file EDMX da solo. Sfortunatamente EntityFramework è impazzito e ha cercato di reinserire entità correlate in altre tabelle, ma è stato comunque un aiuto per aggirare quel messaggio di errore.
FT Winston,

6

Ho avuto lo stesso problema e dopo aver scavato nella progettazione di tabelle in sql server, ho scoperto che erroneamente ho impostato la chiave primaria della tabella anche come chiave esterna.

flusso di progettazione della tabella del server sql

In questa immagine puoi vedere che JobID è la chiave primaria della tabella ma anche erroneamente chiave esterna.


2

Il mio problema era causato dalla definizione ridondante della chiave primaria nella configurazione.

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");

Rimuovi questa riga

.HasDatabaseGeneratedOption (DatabaseGeneratedOption.Identity)


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

Questo è sufficiente per definire la relazione

// 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

1

Ricontrolla la relazione tra Payment e le altre tabelle / entità. Compresi quelli che non dovrebbero contenere PaymentId perché è lì che molto probabilmente si nasconde il problema.

Quando si creano chiavi esterne in SQL Server Management Studio, la chiave primaria viene impostata per impostazione predefinita e questa impostazione predefinita viene ripristinata quando la tabella padre viene modificata, quindi fare attenzione a modificare i valori nell'ordine corretto nella finestra "Tabelle e colonne".

Inoltre, dopo aver risolto la relazione problematica, ci sono buone probabilità che un semplice "Aggiorna" sul modello non rimuova correttamente la relazione errata dal modello e riceverai lo stesso errore anche dopo la " correzione ", quindi fallo tu stesso nel modello prima di eseguire un aggiornamento. (L'ho imparato a mie spese.)


1

Se hai controllato le tue relazioni e sei bravo lì.

Elimina la tabella nell'edmx e quindi aggiorna dal database. Questo ti salverà facendo l'aggiornamento manualmente.


Grazie davvero per il tuo consiglio, ho impiegato 1 ora per convalidare il mio database, ma dopo averlo rimosso e poi aggiornato, è tutto ok.
Tấn Nguyên

1

Per me era una chiave esterna posizionata erroneamente nella tabella, ma anche dopo aver modificato la tabella per risolverlo, non funzionava ancora. È necessario aggiornare i file EDMX (e non abbastanza per "aggiornare" la tabella dal modello, è necessario rimuovere e aggiungere nuovamente la tabella nel modello).


1

Oltre alla risposta accettata, se stai usando il generatore EF Reverse POCO o qualche altro strumento che genera i tuoi POCO, assicurati di rigenerarli !


Non dimenticare mai di rieseguire il tuo strumento T4 personalizzato (tenendo i POCO) dopo aver modificato il tuo generatore di modelli EF DB-first esterno (tenendo i contesti) ... MAI! XD (potrebbe anche essere impazzito -.- ')
Shockwaver

0

Nel mio caso il problema è stato causato dall'avere una relazione 1-1 bidirezionale:

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

Ho dovuto semplicemente rimuovere una delle due chiavi esterne (non necessaria comunque).


0

Nel mio caso è stato semplicemente che non avevo le autorizzazioni impostate correttamente sul database. Avevo letto solo set e Entity framework mi dava un errore ReferentialConstraint che mi ha buttato fuori. Aggiunte autorizzazioni di scrittura aggiuntive e tutto è andato bene.


0

Nel mio caso, avevo una proprietà generata dal database e una proprietà di navigazione ForeignKey impostata per fare riferimento a una tabella correlata da 1 a 1.

Non era qualcosa che potevo rimuovere, dovevo essere in grado di impostare sia la chiave primaria dell'entità su Generato dal database E che dovevo poter fare riferimento alla tabella 1 a 1 come proprietà di navigazione.

Non sono sicuro che sia lo stesso per gli altri, ma questo problema si presentava solo durante la creazione di una nuova entità, la lettura o la modifica di entità esistenti non mostrava il problema, quindi ho aggirato il problema creando una versione ereditata del mio contesto e utilizzando il metodo Fluent per disattivare la proprietà di navigazione durante la creazione.

Quindi, la mia entità originale aveva questo aspetto:

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


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

Quindi ho creato un contesto ereditato speciale simile a questo:

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

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

        }
    }

e quindi modificato il codice che ha creato la nuova entità per renderlo utente del nuovo tipo di contesto

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

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

Spero che questo aiuti qualcuno


0

Nel mio caso il campo Id che FK solo in Entity Framework la proprietà "StoreGeneratedPattern" era impostata su "Itentity" invece di "None"

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.