Programing

EF Code First“잘못된 열 이름 'Discriminator' '이지만 상속은 없습니다.

lottogame 2020. 6. 18. 07:51
반응형

EF Code First“잘못된 열 이름 'Discriminator' '이지만 상속은 없습니다.


데이터베이스에 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

Entity Framework는 파생 클래스가 DB에 저장되지 않더라도 데이터베이스의 테이블에 매핑 된 POCO 클래스에서 상속되는 모든 클래스에 판별 열이 필요하다고 가정합니다.

솔루션은 매우 간단하며 [NotMapped]파생 클래스의 속성으로 추가하면 됩니다.

예:

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

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

이제 Person 클래스를 데이터베이스의 Person 테이블에 매핑하더라도 파생 클래스에는가 있으므로 "Discriminator"열이 만들어지지 않습니다 [NotMapped].

추가 팁으로 [NotMapped]DB의 필드에 매핑하지 않으려는 속성에 사용할 수 있습니다 .


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)을 사용하고 있습니다


이 상황이 발생하는 또 다른 시나리오는 기본 클래스와 하나 이상의 서브 클래스가 있고 하나 이상의 서브 클래스가 추가 특성을 도입하는 경우입니다.

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기본 유형 기반으로하는 유형에 액세스 할 때 " '잘못된 열 이름'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");
}

I found that to fix the issue, we extract the props of Folder to a base class (which is not mapped in OnModelCreating()) like so - OnModelCreating should be unchanged:

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

This eliminates the issue, but I don't know why!


I get the error in another situation, and here are the problem and the solution:

I have 2 classes derived from a same base class named LevledItem:

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

But in their DbContext, I copied some code but forget to change one of the class name:

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

Yes, the second Map< Team> should be Map< Story>. And it cost me half a day to figure it out!


this error happen with me because I did the following

  1. I changed Column name of table in database
  2. (I did not used Update Model from database in Edmx) I Renamed manually Property name to match the change in database schema
  3. I did some refactoring to change name of the property in the class to be the same as database schema and models in Edmx

Although all of this, I got this error

so what to do

  1. I Deleted the model from Edmx
  2. Right Click and Update Model from database

this will regenerate the model, and entity framework will not give you this error

hope this help you


I had a similar problem, not exactly the same conditions and then i saw this post. Hope it helps someone. Apparently i was using one of my EF entity models a base class for a type that was not specified as a db set in my dbcontext. To fix this issue i had to create a base class that had all the properties common to the two types and inherit from the new base class among the two types.

Example:

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

    }

Old Q, but for posterity...it also also happens (.NET Core 2.1) if you have a self-referencing navigation property ("Parent" or "Children" of the same type) but the Id property name isn't what EF expects. That is, I had an "Id" property on my class called WorkflowBase, and it had an array of related child steps, which were also of type WorkflowBase, and it kept trying to associate them with a non-existent "WorkflowBaseId" (the name i suppose it prefers as a natural/conventional default). I had to explicitly configure it using HasMany(), WithOne(), and HasConstraintName() to tell it how to traverse. But I spent a few hours thinking the problem was in 'locally' mapping the object's primary key, which i attempted to fix a bunch of different ways but which was probably always working.

참고URL : https://stackoverflow.com/questions/6553935/ef-code-first-invalid-column-name-discriminator-but-no-inheritance

반응형