Eu tenho uma tabela no meu banco de dados chamada SEntries (veja abaixo a instrução CREATE TABLE). Ele possui uma chave primária, algumas chaves estrangeiras e nada de especial. Tenho muitas tabelas no meu banco de dados semelhantes a essa, mas, por algum motivo, essa tabela acabou com uma coluna "Discriminator" na EF Proxy Class.
É assim que a classe é declarada em C #:
public class SEntry
{
public long SEntryId { get; set; }
public long OriginatorId { get; set; }
public DateTime DatePosted { get; set; }
public string Message { get; set; }
public byte DataEntrySource { get; set; }
public string SourceLink { get; set; }
public int SourceAppId { get; set; }
public int? LocationId { get; set; }
public long? ActivityId { get; set; }
public short OriginatorObjectTypeId { get; set; }
}
public class EMData : DbContext
{
public DbSet<SEntry> SEntries { get; set; }
...
}
Quando tento adicionar uma nova linha a essa tabela, recebo o erro:
System.Data.SqlClient.SqlException: Invalid column name 'Discriminator'.
Esse problema ocorre apenas se você estiver herdando sua classe C # de outra classe, mas o SEntry não está herdando nada (como você pode ver acima).
Além disso, quando recebo a dica de ferramenta no depurador quando passo o mouse sobre a instância EMData da propriedade SEntries, ela exibe:
base {System.Data.Entity.Infrastructure.DbQuery<EM.SEntry>} = {SELECT
[Extent1].[Discriminator] AS [Discriminator],
[Extent1].[SEntryId] AS [SEntryId],
[Extent1].[OriginatorId] AS [OriginatorId],
[Extent1].[DatePosted] AS [DatePosted],
[Extent1].[Message] AS [Message],
[Extent1].[DataEntrySource] AS [DataE...
Alguma sugestão ou idéia de onde chegar ao fundo desta edição? Tentei renomear a tabela, a chave primária e algumas outras coisas, mas nada funciona.
Tabela SQL:
CREATE TABLE [dbo].[SEntries](
[SEntryId] [bigint] IDENTITY(1125899906842624,1) NOT NULL,
[OriginatorId] [bigint] NOT NULL,
[DatePosted] [datetime] NOT NULL,
[Message] [nvarchar](500) NOT NULL,
[DataEntrySource] [tinyint] NOT NULL,
[SourceLink] [nvarchar](100) NULL,
[SourceAppId] [int] NOT NULL,
[LocationId] [int] NULL,
[ActivityId] [bigint] NULL,
[OriginatorObjectTypeId] [smallint] NOT NULL,
CONSTRAINT [PK_SEntries] PRIMARY KEY CLUSTERED
(
[SEntryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[SEntries] WITH CHECK ADD CONSTRAINT [FK_SEntries_ObjectTypes] FOREIGN KEY([OriginatorObjectTypeId])
REFERENCES [dbo].[ObjectTypes] ([ObjectTypeId])
GO
ALTER TABLE [dbo].[SEntries] CHECK CONSTRAINT [FK_SEntries_ObjectTypes]
GO
ALTER TABLE [dbo].[SEntries] WITH CHECK ADD CONSTRAINT [FK_SEntries_SourceApps] FOREIGN KEY([SourceAppId])
REFERENCES [dbo].[SourceApps] ([SourceAppId])
GO
ALTER TABLE [dbo].[SEntries] CHECK CONSTRAINT [FK_SEntries_SourceApps]
GO
fonte
Respostas:
Acontece que o Entity Framework assumirá que qualquer classe que herda de uma classe POCO que é mapeada para uma tabela no banco de dados requer uma coluna Discriminator, mesmo que a classe derivada não seja salva no DB.
A solução é bastante simples e você só precisa adicionar
[NotMapped]
como um atributo da classe derivada.Exemplo:
Agora, mesmo se você mapear a classe Person para a tabela Person no banco de dados, uma coluna "Discriminator" não será criada porque a classe derivada possui
[NotMapped]
.Como uma dica adicional, você pode usar
[NotMapped]
para propriedades que não deseja mapear para um campo no banco de dados.fonte
Aqui está a sintaxe da API Fluent.
http://blogs.msdn.com/b/adonet/archive/2010/12/06/ef-feature-ctp5-fluent-api-samples.aspx
fonte
[NotMapped]
atributo?Acabei de encontrar isso e meu problema foi causado por ter duas entidades, ambas
System.ComponentModel.DataAnnotations.Schema.TableAttribute
referindo-se à mesma tabela.por exemplo:
alterando o segundo de
foo
parafoo_extended
corrigido isso para mim e agora estou usando a tabela por tipo (TPT)fonte
The entity types 'AtencionMedica' and 'AtencionMedicaAP' cannot share table 'AtencionMedicas' because they are not in the same type hierarchy
var entity = modelBuilder.Entity<EntityObject>().ToTable("ENTITY_TABLE")
e, em seguida, outra linha usando o mesmoEntityObject
ou o mesmoENTITY_TABLE
.Outro cenário em que isso ocorre é quando você tem uma classe base e uma ou mais subclasses, em que pelo menos uma das subclasses apresenta propriedades extras:
Se eles estiverem mapeados da
DbContext
seguinte maneira, o erro "'Nome da coluna inválido' Discriminador '" ocorrerá quando qualquer tipo comFolder
base no tipo base for acessado:Descobri que, para corrigir o problema, extraímos os adereços de
Folder
uma classe base (que não é mapeadaOnModelCreating()
) como tal -OnModelCreating
deve permanecer inalterada:Isso elimina o problema, mas não sei por que!
fonte
Eu recebo o erro em outra situação, e aqui estão o problema e a solução:
Eu tenho 2 classes derivadas de uma mesma classe base chamada LevledItem:
Mas no DbContext, copiei algum código, mas esqueço de alterar um dos nomes da classe:
Sim, o segundo mapa <equipe> deve ser o mapa <história>. E me custou meio dia para descobrir!
fonte
Eu tive um problema semelhante, não exatamente as mesmas condições e então vi este post . Espero que ajude alguém. Aparentemente, eu estava usando um dos meus modelos de entidade EF uma classe base para um tipo que não foi especificado como um db definido no meu dbcontext. Para corrigir esse problema, tive que criar uma classe base que tivesse todas as propriedades comuns aos dois tipos e herdar a nova classe base entre os dois tipos.
Exemplo:
fonte
esse erro aconteceu comigo porque eu fiz o seguinte
Update Model from database
no Edmx) Renomeei manualmente Nome da propriedade para corresponder à alteração no esquema do banco de dadosEmbora tudo isso, eu recebi esse erro
tão
what to do
Update Model from database
isso irá regenerar o modelo, e a estrutura da entidade
will
nãogive you this error
espero que isso ajude você
fonte
Q antigo, mas para a posteridade ... também acontece (.NET Core 2.1) se você tiver uma propriedade de navegação de referência própria ("Pai" ou "Filhos" do mesmo tipo), mas o nome da propriedade Id não for o que A EF espera. Ou seja, eu tinha uma propriedade "Id" na minha classe chamada
WorkflowBase
e ela tinha uma matriz de etapas filho relacionadas, que também eram do tipoWorkflowBase
, e continuava tentando associá-las a um "WorkflowBaseId" inexistente (o nome i suponha que prefira como padrão natural / convencional). Eu tive que configurá-lo explicitamente usandoHasMany()
,WithOne()
eHasConstraintName()
contá-la como atravessar. Mas passei algumas horas pensando que o problema estava no mapeamento 'local' da chave primária do objeto, que tentei corrigir de várias maneiras diferentes, mas que provavelmente estava sempre funcionando.fonte