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.