EF 代码首先“无效的列名‘鉴别器’”,但没有继承

我在数据库中有一个名为 SEntry 的表(请参见 CREATETABLE 语句的下面)。它有一个主键,几个外键,没有什么特别之处。我的数据库中有许多类似的表,但由于某种原因,这个表最终在 EF 代理类上显示了一个“鉴别器”列。

这就是类在 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 没有从任何类继承(正如您在上面看到的)。

此外,当我在 SEntry 属性的 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-Table:

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
124832 次浏览

原来,实体框架将假定,从映射到数据库表的 POCO 类继承的任何类都需要一个鉴别器列,即使派生类不会保存到数据库中。

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

例如:

class Person
{
public string Name { get; set; }
}


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

现在,即使将 Person 类映射到数据库上的 Person 表,也不会创建“鉴别器”列,因为派生类具有 [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为我固定这一点,我现在使用表每类型(TPT)

我在另一种情况下得到了错误,下面是问题和解决方案:

我有两个派生自同一个名为 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 > 。 我花了半天才想明白!

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

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应该保持不变:

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. (我在 Edmx 中没有使用 Update Model from database)我手动重命名属性名以匹配数据库模式中的更改
  3. 我进行了一些重构,将类中属性的名称更改为与 Edmx 中的数据库模式和模型相同

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

所以 what to do

  1. 我删除了 Edmx 的模型
  2. 右击和 Update Model from database

这将重新生成模型和实体框架 will 没有 give you this error

希望这个能帮到你

我有过类似的问题,不完全相同的条件,然后我看到了 这篇文章。希望能帮到别人。显然,我使用了一个 EF 实体模型作为一个基类,这个类型在 dbcontext 中没有指定为 db 集。为了解决这个问题,我必须创建一个基类,它拥有这两种类型的所有公共属性,并从这两种类型之间的新基类继承。

例如:

//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;}


}

老 Q,但对后人来说... ... 它也发生了(。NET Core 2.1) ,如果你有一个自我引用的导航属性(“ Parent”或“ Children”的相同类型) ,但 Id 属性名称不是 EF 所期望的。也就是说,我在我的类中有一个名为 WorkflowBase的“ Id”属性,它有一个相关的子步骤数组,也是 WorkflowBase类型,并且它一直试图将它们与一个不存在的“ Workflow BaseId”(我想它更喜欢作为一个自然/常规的默认名称)关联起来。我必须使用 HasMany()WithOne()HasConstraintName()显式地配置它,以告诉它如何遍历。但是我花了几个小时思考,问题在于“本地”映射对象的主键,我试图修复一些不同的方法,但可能一直都在工作。