我的数据库中有一个名为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'.
只有从其他类继承C#类时才会出现此问题,但SEntry不会从任何类继承(如上所示)。
除此之外,当我将鼠标悬停在SEntries属性的EMData实例上时,一旦我在调试器上获得了工具提示,它就会显示:
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...
有什么建议或想法可以解决这个问题的根源吗?我尝试重命名表,主键和其他一些东西,但没有任何作用。
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
答案 0 :(得分:298)
事实证明,Entity Framework将假定从映射到数据库中的表的POCO类继承的任何类都需要Discriminator列,即使派生类不会保存到数据库中。
解决方案非常简单,您只需添加[NotMapped]
作为派生类的属性。
示例:
class Person
{
public string Name { get; set; }
}
[NotMapped]
class PersonViewModel : Person
{
public bool UpdateProfile { get; set; }
}
现在,即使将Person类映射到数据库上的Person表,也不会创建“Discriminator”列,因为派生类具有[NotMapped]
。
作为附加提示,您可以将[NotMapped]
用于您不想映射到数据库字段的属性。
答案 1 :(得分:41)
以下是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);
}
答案 2 :(得分:7)
我刚刚遇到这个问题,我的问题是由两个实体同时引用同一个表System.ComponentModel.DataAnnotations.Schema.TableAttribute
引起的。
例如:
[Table("foo")]
public class foo
{
// some stuff here
}
[Table("foo")]
public class fooExtended
{
// more stuff here
}
将第二个从foo
更改为foo_extended
为我解决此问题,我现在正在使用每种类型的表格(TPT)
答案 3 :(得分:3)
发生这种情况的另一种情况是,当你有一个基类和一个或多个子类时,其中至少有一个子类引入了额外的属性:
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
基类型的任何类型时,会出现“'无效列名'判别器'”错误:
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
应该保持不变:< / p>
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; }
}
这消除了这个问题,但我不知道为什么!
答案 4 :(得分:2)
我在另一种情况下得到错误,这是问题和解决方案:
我有2个派生自同一个名为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));
}
是的,第二张地图&lt;团队及GT;应该是Map&lt;故事取代。 我花了半天时间才想出来!
答案 5 :(得分:1)
这个错误发生在我身上,因为我做了以下
Update Model from database
)我手动重命名属性名称以匹配数据库架构中的更改尽管如此,我收到了这个错误
所以what to do
Update Model from database
这将重新生成模型,实体框架will
不 give you this error
希望这能帮到你
答案 6 :(得分:1)
我遇到了类似的问题,条件并不完全相同,然后我看到了this post。希望它可以帮助某人。显然,我使用的是我的EF实体模型之一,该类的基类未在dbcontext中指定为数据库集。要解决此问题,我必须创建一个具有两种类型共有的所有属性的基类,并从这两种类型中的新基类继承。
示例:
//Bad Flow
//class defined in dbcontext as a dbset
public class Customer{
public int Id {get; set;}
public string Name {get; set;}
}
//class not defined in dbcontext as a dbset
public class DuplicateCustomer:Customer{
public object DuplicateId {get; set;}
}
//Good/Correct flow*
//Common base class
public class CustomerBase{
public int Id {get; set;}
public string Name {get; set;}
}
//entity model referenced in dbcontext as a dbset
public class Customer: CustomerBase{
}
//entity model not referenced in dbcontext as a dbset
public class DuplicateCustomer:CustomerBase{
public object DuplicateId {get; set;}
}
答案 7 :(得分:0)
旧Q,但是对于后代来说,如果您具有自引用导航属性(相同类型的“父”或“子”),但Id属性名称不是,也将发生(.NET Core 2.1)这不是EF的期望。也就是说,我在我的类上有一个名为WorkflowBase
的“ Id”属性,它具有一系列相关的子步骤,这些子步骤的类型也为WorkflowBase
,并且它一直尝试将它们与一个不存在的“ WorkflowBaseId”(我认为它更喜欢使用自然/常规默认名称)。我必须使用HasMany()
,WithOne()
和HasConstraintName()
对其进行显式配置,以告诉它如何遍历。但是我花了几个小时认为问题出在“本地”映射对象的主键上,我试图修复一堆不同的方法,但是这种方法可能一直有效。