EF代码优先“无效的列名”歧视“”但没有inheritance

我在我的数据库中有一个名为SEntries的表(请参阅下面的CREATE TABLE语句)。 它有一个主键,一对外键,没有什么特别的。 在我的数据库中有很多类似于这个表的表,但是由于某种原因,这个表最终在EF代理类上有一个“Discriminator”列。

这是如何在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; } ... } 

当我尝试向该表添加新行时,出现错误:

 System.Data.SqlClient.SqlException: Invalid column name 'Discriminator'. 

如果您从另一个类inheritance您的C#类,则只会发生此问题,但是SEntry不会从任何东西inheritance(如上所示)。

除此之外,当我将鼠标hover在SEntries属性的EMData实例上时,一旦我在debugging器上获得了工具提示,它将显示:

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

任何build议或想法在哪里得到这个问题的底部? 我尝试重命名表,主键和其他一些东西,但没有任何工作。

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 

事实certificate,entity framework将假设从映射到数据库表上的POCO类inheritance的任何类都需要Discriminator列,即使派生类不会保存到数据库中。

解决scheme非常简单,只需要将[NotMapped]添加为派生类的属性即可。

例:

 class Person { public string Name { get; set; } } [NotMapped] class PersonViewModel : Person { public bool UpdateProfile { get; set; } } 

现在,即使将Person类映射到数据库上的Person表,也不会创build“Discriminator”列,因为派生类具有[NotMapped]

作为附加提示,您可以使用[NotMapped]指定不想映射到数据库字段的属性。

这里是Fluent API语法。

http://blogs.msdn.com/b/adonet/archive/2010/12/06/ef-feature-ctp5-fluent-api-samples.aspx

 class Person { public string FirstName { get; set; } public string LastName { get; set; } public string FullName { get { return this.FirstName + " " + this.LastName; } } } class PersonViewModel : Person { public bool UpdateProfile { get; set; } } protected override void OnModelCreating(DbModelBuilder modelBuilder) { // ignore a type that is not mapped to a database table modelBuilder.Ignore<PersonViewModel>(); // ignore a property that is not mapped to a database column modelBuilder.Entity<Person>() .Ignore(p => p.FullName); } 

我刚刚遇到这个,我的问题是由两个实体引用同一个表的System.ComponentModel.DataAnnotations.Schema.TableAttribute造成的。

例如:

 [Table("foo")] public class foo { // some stuff here } [Table("foo")] public class fooExtended { // more stuff here } 

改变第二个从foofoo_extended固定这个对我来说,我现在使用每种types表(TPT)

我在另一种情况下得到错误,这里是问题和解决scheme:

我有两个类从名为LevledItem相同的基类派生:

 public partial class Team : LeveledItem { //Everything is ok here! } public partial class Story : LeveledItem { //Everything is ok here! } 

但是在他们的DbContext中,我复制了一些代码,但忘了更改其中的一个类名:

 public class MFCTeamDbContext : DbContext { protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Other codes here modelBuilder.Entity<LeveledItem>() .Map<Team>(m => m.Requires("Type").HasValue(ItemType.Team)); } public class ProductBacklogDbContext : DbContext { protected override void OnModelCreating(DbModelBuilder modelBuilder) { //Other codes here modelBuilder.Entity<LeveledItem>() .Map<Team>(m => m.Requires("Type").HasValue(ItemType.Story)); } 

是的,第二个Map <Team>应该是Map <Story>。 花费我半天的时间才能搞清楚!

发生这种情况的另一个场景是当您有一个基类和一个或多个子类,其中至less有一个子类引入额外的属性:

 class Folder { [key] public string Id { get; set; } public string Name { get; set; } } // Adds no props, but comes from a different view in the db to Folder: class SomeKindOfFolder: Folder { } // Adds some props, but comes from a different view in the db to Folder: class AnotherKindOfFolder: Folder { public string FolderAttributes { get; set; } } 

如果这些映射到下面的DbContext中,则在访问基于Folder基本types的任何types时,会发生“无效列名”Discriminator“”错误:

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Folder>().ToTable("All_Folders"); modelBuilder.Entity<SomeKindOfFolder>().ToTable("Some_Kind_Of_Folders"); modelBuilder.Entity<AnotherKindOfFolder>().ToTable("Another_Kind_Of_Folders"); } 

我发现要解决这个问题,我们将Folder的道具提取到一个基类(它没有在OnModelCreating()映射),像这样 – OnModelCreating应该是不变的:

 class FolderBase { [key] public string Id { get; set; } public string Name { get; set; } } class Folder: FolderBase { } class SomeKindOfFolder: FolderBase { } class AnotherKindOfFolder: FolderBase { public string FolderAttributes { get; set; } } 

这消除了这个问题,但我不知道为什么!

这个错误发生在我身上,因为我做了以下事情

  1. 我改变了数据库中表的列名
  2. (我没有使用Update Model from database Edmx Update Model from database )我手动重命名属性名称以匹配数据库架构中的更改
  3. 我做了一些重构,将类中属性的名称更改为与Edmx中的数据库模式和模型相同

虽然所有这一切,我得到了这个错误

what to do

  1. 我从Edmx删除了模型
  2. 右键单击并Update Model from database

这将重新生成模型,entity framework不会 give you this error

希望这对你有所帮助