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 }
改变第二个从foo
到foo_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; } }
这消除了这个问题,但我不知道为什么!
这个错误发生在我身上,因为我做了以下事情
- 我改变了数据库中表的列名
- (我没有使用
Update Model from database
EdmxUpdate Model from database
)我手动重命名属性名称以匹配数据库架构中的更改 - 我做了一些重构,将类中属性的名称更改为与Edmx中的数据库模式和模型相同
虽然所有这一切,我得到了这个错误
what to do
- 我从Edmx删除了模型
- 右键单击并
Update Model from database
这将重新生成模型,entity framework不会 give you this error
希望这对你有所帮助
- 如何在Entity Framework Code First中分离对象?
- 我在哪里可以find在包pipe理器窗口中执行的代码的控制台或debugging输出?
- 我应该启用还是禁用dynamic代理与entity framework4.1和MVC3?
- 重写SaveChanges并设置ModifiedDate,但是如何设置ModifiedBy?
- EF模式首先或代码优先的方法?
- StringLength与MaxLength属性entity frameworkEF Code First的ASP.NET MVC
- MapKey与HasForeignKey差异 – Fluent Api
- 首先使用EF代码的唯一键
- entity framework代码首先将Guid用作另一个标识列的标识