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

Rei galês
fonte

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.

ju4nj3
fonte
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).

Ladislav Mrnka
fonte
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.

surfar
fonte
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.

Manish Bhakuni
fonte
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
Piotr
fonte
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.)

Marca
fonte
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.

Rickjr82
fonte
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).

knocte
fonte
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!

adam0101
fonte
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).

wecky
fonte
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.

Mdhattr
fonte
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

Chris Terry
fonte
0

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

Lev K.
fonte