Uma propriedade dependente em um ReferentialConstraint é mapeada para uma coluna gerada pela loja


98

Recebo este erro ao gravar no banco de dados:

Uma propriedade dependente em um ReferentialConstraint é mapeada para uma coluna gerada pela loja. Coluna: '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;
    }

O esquema é:

insira a descrição da imagem aqui

Respostas:


180

É possível que você tenha definido uma relação de coluna incorreta entre suas tabelas? colunas diferentes e uma foi definida como autonumérica.

Isso aconteceu comigo.


55
Por engano, tornei uma das minhas chaves estrangeiras uma identidade (incremento automático). Este é o erro que recebi.
— jocull

3
Doh! Eu deixei a parte da chave estrangeira do relacionamento como o padrão fornecido pelo SQL Server 2008 Management Studio, que eram os campos de chave primária da tabela filho, não a coluna que criei para conter o valor da chave estrangeira.
— robaker

12
Se você inspecionar a exceção na janela Quick Watch (ou seja (e as System.Data.Entity.Infrastructure.DbUpdateException).Entries,), poderá ver qual tabela contém a chave primária sendo referenciada.
— Cᴏʀʏ

17
Não seria legal se as mensagens de erro do EF apenas declarassem qual era o problema, em vez de cuspir gobbledy-gook?
— AR

Usei esta consulta para visualizar todos os relacionamentos em uma visualização stackoverflow.com/questions/8094156/…
— Dave

47

Este erro diz que você está usando relação não suportada ou que há um erro no seu mapeamento. Provavelmente, seu código não está relacionado ao erro.

O erro significa que você tem alguma relação entre entidades em que a propriedade da chave estrangeira na entidade dependente é definida como gerada pelo armazenamento. As propriedades geradas pela loja são preenchidas no banco de dados. EF não oferece suporte a armazenar propriedades geradas como chaves estrangeiras (bem como propriedades computadas em chaves primárias).


2
posso adicionar a linha no servidor sql com as mesmas informações. quando você diz Store Generated, pode dar um exemplo?
— Rei Galês de

1
EF não é SQL Server. Ele tem sua própria limitação. Simplesmente encontre onde você usa qualquer propriedade FK gerada pelo banco de dados chamada PaymentIDe trate disso.
— Ladislav Mrnka

ok, temos uma tabela de histórico de pagamentos que tem paymentId como uma chave estrangeira, preciso adicionar uma linha lá?
— Rei Galês de

Não se trata de adicionar linhas, mas sim de definir a coluna. Como você define essa coluna?
— Ladislav Mrnka

apenas cliquei no modelo de relacionamento no visual studio e estou recebendo Nome 'Pagamento' não pode ser usado no tipo 'Pagamento'. os nomes dos membros não podem ser iguais aos do tipo delimitador. Quaisquer ideias
— Welsh King

8

Eu tive o mesmo problema. Com base nas respostas fornecidas aqui, fui capaz de rastreá-lo e resolvê-lo, mas tive um problema estranho descrito abaixo - pode ajudar alguém no futuro.

Em minhas tabelas dependentes, as colunas de chave estrangeira foram definidas como StoreGeneratedPattern = "Identity". Tive que mudar para "Nenhum". Infelizmente, fazer isso por dentro do designer não funcionou.

Eu olhei no XML gerado pelo designer (SSDL) e essas propriedades ainda estavam lá, então eu as removi manualmente. Também tive que consertar as colunas do banco de dados (remover a identidade (1,1) de CREATE TABLE SQL)

Depois disso, o problema foi embora.


Obrigado por esta dica. Alterar o campo no designer de Identidade para Nenhum alterou isso em um lugar no EDMX, mas não no outro, então ainda recebi o erro até que editei o arquivo EDMX sozinho. Infelizmente, EntityFramework então enlouqueceu e tentou reinserir entidades relacionadas em outras tabelas, mas ainda assim, foi uma ajuda para contornar aquela mensagem de erro.
— FTWinston

6

Eu tive o mesmo problema e depois de pesquisar no design da tabela no sql server, descobri que, por engano, configurei a chave primária da tabela também como chave estrangeira.

fluxo de design da tabela do servidor sql

Nesta imagem você pode ver que JobID é a chave primária da tabela, mas também a chave estrangeira por engano.


2

Meu problema foi causado pela definição redundante da chave primária na configuração.

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

Remova esta linha

.HasDatabaseGeneratedOption (DatabaseGeneratedOption.Identity)


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

Isso é o suficiente para definir a relação

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

Verifique novamente a relação entre o Pagamento e as outras tabelas / entidades. Incluindo aqueles que não deveriam conter PaymentId, porque é onde o problema provavelmente está escondido.

Ao criar chaves externas no SQL Server Management Studio, a chave primária é padronizada, e esse padrão é revertido quando a tabela pai é alterada, portanto, tome cuidado para alterar os valores na ordem correta na janela "Tabelas e colunas".

Além disso, depois de corrigir o relacionamento problemático, há uma boa chance de que um simples "Atualizar" no modelo não remova corretamente o relacionamento incorreto do modelo e você receberá o mesmo erro mesmo após a " correção ", portanto, faça você mesmo no modelo antes de realizar uma atualização. (Descobri isso da maneira mais difícil.)


1

Se você verificou seus relacionamentos e está bem lá.

Exclua a tabela no edmx e atualize do banco de dados. Isso evitará que você faça a atualização manualmente.


Agradeço muito pelo seu conselho, passei 1 hora validando meu banco de dados, mas depois de removido e atualizado, está tudo ok.
— Tấn Nguyên

1

Para mim, era uma chave estrangeira colocada incorretamente na tabela, mas mesmo depois de alterar a tabela para corrigi-la, ainda não estava funcionando. Você precisa atualizar os arquivos EDMX (e não o suficiente para "atualizar" a tabela do modelo, você precisa remover e adicionar a tabela novamente no modelo).


1

Além da resposta aceita, se você estiver usando EF reverso POCO gerador ou alguma outra ferramenta que gera o seu POCO, certifique-se de regenerar -los!


Nunca se esqueça de executar novamente sua ferramenta T4 personalizada (segurando os POCOs) depois de modificar seu gerador de modelo EF DB-first externo (segurando os contextos) ... SEMPRE! XD (poderia muito bem ter ficado louco -.- ')
— Shockwaver

0

No meu caso, o problema foi causado por ter um relacionamento 1-1 bidirecional:

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

Tive que simplesmente remover uma das duas chaves estrangeiras (não é necessário de qualquer maneira).


0

No meu caso, era simplesmente porque eu não tinha as permissões definidas corretamente no banco de dados. Eu tinha lido apenas set e o framework Entity estava me dando um erro ReferentialConstraint que me confundiu. Adicionadas permissões de gravação adicionais e tudo estava bem.


0

No meu caso, eu tinha uma propriedade Database Generated e uma propriedade de navegação ForeignKey configurada para fazer referência a uma tabela relacionada de 1 para 1.

Isso não era algo que eu pudesse remover, eu precisava ser capaz de definir a chave primária da entidade para ser gerado pelo banco de dados E precisava ser capaz de fazer referência à tabela 1 para 1 como uma propriedade de navegação.

Não tenho certeza se isso é o mesmo para os outros, mas esse problema só aparecia ao criar uma nova entidade, ler ou editar entidades existentes não exibia o problema, então resolvi o problema criando uma versão herdada do meu Contexto e usando o método Fluent para desligar a propriedade de navegação ao criar.

Então, minha entidade original era assim:

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


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

Então, criei um contexto herdado especial que se parecia com este:

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

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

        }
    }

e então mudou o código que criou a nova entidade para tornar o usuário do novo tipo de contexto

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

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

Espero que isso ajude alguém


0

No meu caso, o campo Id que é FK apenas no Entity Framework a propriedade "StoreGeneratedPattern" foi definida como "Itentity" em vez de "None"

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.