Una propiedad dependiente en un ReferentialConstraint se asigna a una columna generada por la tienda

98

Recibo este error al escribir en la base de datos:

Una propiedad dependiente en un ReferentialConstraint se asigna a una columna generada por la tienda. Columna: '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;
    }

El esquema es:

ingrese la descripción de la imagen aquí

Rey galés
fuente

Respuestas:

180

¿Es posible que haya definido una mala relación de columna entre sus tablas? columnas diferentes y una se estableció como autonumérica.

Me pasó a mi.

ju4nj3
fuente
55
Hice por error una de mis claves externas como Identidad (incremento automático). Este es el error que obtuve.
jocull
3
Doh! Dejé la parte de clave externa de la relación como predeterminada dada por SQL Server 2008 Management Studio, que eran los campos de clave primaria de la tabla secundaria, no la columna que había creado para contener el valor de clave externa.
robaker
12
Si inspecciona la excepción en la ventana Quick Watch (es decir (e as System.Data.Entity.Infrastructure.DbUpdateException).Entries), puede ver qué tabla contiene la clave principal a la que se hace referencia.
Cᴏʀʏ
17
¿No sería genial si los mensajes de error de EF solo indicaran cuál es el problema en lugar de escupir palabrería?
AR
Usé esta consulta para ver todas las relaciones en una vista stackoverflow.com/questions/8094156/…
Dave
47

Este error dice que está utilizando una relación no admitida o tiene un error en su mapeo. Es muy probable que su código no tenga ninguna relación con el error.

El error significa que tiene alguna relación entre entidades donde la propiedad de clave externa en la entidad dependiente se define como generada por la tienda. Las propiedades generadas por la tienda se rellenan en la base de datos. EF no admite propiedades generadas por la tienda como claves externas (así como propiedades calculadas en claves primarias).

Ladislav Mrnka
fuente
2
Puedo agregar la fila en el servidor SQL con la misma información. cuando dice Store Generated, ¿puede dar un ejemplo?
Welsh King
1
EF no es SQL Server. Tiene su propia limitación. Simplemente busque dónde usa cualquier propiedad FK generada por DB llamada PaymentIDy maneje con ella.
Ladislav Mrnka
ok, tenemos una tabla de historial de pagos que tiene paymentId como clave externa, ¿necesito agregar una fila allí?
Welsh King
No se trata de agregar una fila, sino de definir la columna. ¿Cómo pones esa columna?
Ladislav Mrnka
Acabo de hacer clic en el modelo de relación en Visual Studio y obtengo el nombre 'Pago' que no se puede usar en el tipo 'Pago'. los nombres de los miembros no pueden ser los mismos que el tipo que los adjunta. Cualquier idea
Rey de Gales
8

Yo tuve el mismo problema. Según las respuestas proporcionadas aquí, pude rastrearlo y resolverlo, pero tuve un problema extraño que se describe a continuación: podría ayudar a alguien en el futuro.

En mis tablas dependientes, las columnas de clave externa se han establecido en StoreGeneratedPattern = "Identity". Tuve que cambiarlo a "Ninguno". Desafortunadamente, hacerlo dentro del diseñador no funcionó en absoluto.

Busqué en el XML generado por el diseñador (SSDL) y estas propiedades todavía estaban allí, así que las eliminé manualmente. También tuve que arreglar las columnas en la base de datos (eliminar la Identidad (1,1) de CREATE TABLE SQL)

Después de eso, el problema desapareció.

surfear
fuente
Gracias por este consejo. Cambiar el campo en el diseñador de Identidad a Ninguno cambió esto en un lugar en el EDMX, pero no en el otro lugar, así que todavía recibí el error hasta que edité el archivo EDMX yo mismo. Desafortunadamente, EntityFramework se volvió loco e intentó volver a insertar entidades relacionadas en otras tablas, pero aún así, fue una ayuda para evitar ese mensaje de error.
FTWinston
6

Tuve el mismo problema y después de investigar un poco el diseño de la tabla en el servidor SQL, descubrí que, por error, configuré la clave principal de la tabla también como clave externa.

flujo de diseño de la tabla del servidor sql

En esta imagen, puede ver que JobID es la clave principal de la tabla, pero también es una clave foránea por error.

Manish Bhakuni
fuente
2

Mi problema fue causado por la definición redundante de la clave principal en la configuración.

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

Quitar esta línea

.HasDatabaseGeneratedOption (DatabaseGeneratedOption.Identity)


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

Esto es suficiente para definir la relación.

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

Vuelva a verificar la relación entre Pago y las otras tablas / entidades. Incluyendo los que no deberían contener PaymentId porque ahí es donde es más probable que se esconda el problema.

Al crear claves foráneas en SQL Server Management Studio, la clave principal está predeterminada, y esta predeterminada se revierte cuando se cambia la tabla principal, así que tenga cuidado de cambiar los valores en el orden correcto en la ventana "Tablas y columnas".

Además, una vez que haya solucionado la relación problemática, es muy probable que un simple "Actualizar" en el modelo no elimine correctamente la relación errónea del modelo y obtendrá el mismo error incluso después de la " reparación ", así que hágalo usted mismo en el modelo antes de realizar una actualización. (Descubrí esto por las malas).

marca
fuente
1

Si ha comprobado sus relaciones y está bien allí.

Elimine la tabla en el edmx y luego actualice desde la base de datos. Esto le evitará realizar la actualización manualmente.

rickjr82
fuente
Realmente gracias por su consejo, pasé 1 hora para validar mi base de datos, pero después de eliminarla y actualizarla, todo está bien.
Tấn Nguyên
1

Para mí, era una clave externa colocada incorrectamente en la tabla, pero incluso después de alterar la tabla para arreglarla, todavía no funcionaba. Debe actualizar los archivos EDMX (y no lo suficiente para "actualizar" la tabla del modelo, debe eliminar y agregar la tabla nuevamente en el modelo).

knocte
fuente
1

Además de la respuesta aceptada, si está utilizando el generador EF Reverse POCO o alguna otra herramienta que genere sus POCO, ¡asegúrese de regenerarlos !

adam0101
fuente
Nunca olvide volver a ejecutar su Herramienta T4 personalizada (sosteniendo los POCO) después de modificar su generador de modelo EF de DB-first externo (manteniendo los contextos) ... ¡NUNCA! XD (también podría haberse vuelto loco -.- ')
Shockwaver
0

En mi caso, el problema fue causado por tener una relación 1-1 de dos vías:

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

Simplemente tuve que eliminar una de las dos claves externas (no es necesario de todos modos).

wecky
fuente
0

En mi caso, fue simplemente que no tenía los permisos establecidos correctamente en la base de datos. Había leído solo un conjunto y Entity framework me estaba dando un error ReferentialConstraint que me desconcertó. Se agregaron permisos de escritura adicionales y todo estuvo bien.

Mdhattr
fuente
0

En mi caso, tenía una propiedad de base de datos generada y una propiedad de navegación ForeignKey configurada para hacer referencia a una tabla relacionada 1 a 1.

Esto no era algo que pudiera eliminar, necesitaba poder configurar la clave principal de la entidad para que se generara en la base de datos Y necesitaba poder hacer referencia a la tabla 1 a 1 como una propiedad de navegación.

No estoy seguro de si esto es lo mismo para otros, pero este problema solo aparecía cuando se creaba una nueva entidad, leer o editar entidades existentes no mostraba el problema, así que solucioné el problema creando una versión heredada de mi contexto y usando el método Fluent para desactivar la propiedad de navegación al crear.

Entonces, mi entidad original se veía así:

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


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

Así que hice un contexto heredado especial que se veía así:

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

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

        }
    }

y luego cambió el código que creó la nueva entidad para hacer usuario del nuevo tipo de contexto

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

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

Espero que esto ayude a alguien

Chris Terry
fuente
0

En mi caso, el campo Id que FK solo en Entity Framework, la propiedad "StoreGeneratedPattern" se estableció en "Itentity" en lugar de "None"

Lev K.
fuente