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


154

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

16
이것을 알아 내려고 시간을 할애하는 다음 사람에게는 코드의 다른 곳에서 SEntry에서 상속받은 클래스가 있었지만 DB에 저장된 클래스는 아니지만 . 따라서 내가해야 할 일은 [NotMapped]를 해당 클래스의 속성으로 추가하는 것입니다!
Marcelo Calbucci

내가 Identitymodel.cs에 ApplicationUser 클래스에 [NotMapped]을 넣어하지 않는 경우이 오류가 무엇입니까
Heemanshu Bhalla을

답변:


319

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의 필드에 매핑하지 않으려는 속성에 사용할 수 있습니다 .


7
좋아, 그래서 내 인생의 3 시간이 간다. 여전히 혼란스러워 할 것입니다.
rism

12
[NotMapped]를 찾을 수 없으면 "Assembly Framework"에서 "System.ComponentModel.DataAnnotations"에 대한 참조를 프로젝트에 추가하십시오.
XandrUu

9
System.ComponentModel.DataAnnotations.Schema 사용;
ygaradon

6
하지만 제 경우에는 자식 클래스를 사용하여 db 테이블에 열을 추가하기 위해 클래스를 상속했습니다. 그래서이 매핑되지 않은 속성을 사용하여 작동시키지 않습니다. 이 경우 내 해결책은 무엇입니까?
sohaib는

4
내 경우에는 매핑되지 않은 추가가 도움이되지 않았습니다. 나는 모든 뷰 모델에서 맵되지 않았다
Heemanshu Bhalla

44

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

}

[NotMapped]속성 을 추가하는 것이 낫지 않습니까?
Keith

1
내 대답은 유창함 API, 수행하는 사용과 같은 [NotMapped] 속성을하지를 사용하여 열을 무시하는 방법입니다 @Keith
월터 Stabosz

1
Keith 이것은 코드 우선 표준으로 나아가고 있기 때문에 내가 선호하는 대답이며 Walter의 대답은 특히 DB 마이그레이션을 사용하는 경우이 시나리오에 더 적합합니다.
Tahir Khalid

반대의 문제가있는 경우 (예 : POCO 클래스에서 상속되는 EF 바운드 클래스) EF로 데이터 모델을 오염시키지 않고 작동 할 수있는 유일한 방법이었습니다.
Paul Michaels

8

방금이 문제가 발생했으며 System.ComponentModel.DataAnnotations.Schema.TableAttribute동일한 테이블을 참조하는 두 개의 엔티티가 모두있어서 문제가 발생했습니다 .

예를 들면 다음과 같습니다.

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

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

에서 두 번째 변화 foofoo_extended날 위해 고정 지금은 테이블 당 형식 (TPT)을 사용하고 있습니다


이것은 나를 위해 작동하지 않았다 :The entity types 'AtencionMedica' and 'AtencionMedicaAP' cannot share table 'AtencionMedicas' because they are not in the same type hierarchy
제임스 Reategui

고마워, 유창한 API를 사용하여 같은 문제가 발생했습니다. var entity = modelBuilder.Entity<EntityObject>().ToTable("ENTITY_TABLE")그리고 같은 EntityObject또는 같은 다른 줄을 사용했습니다 ENTITY_TABLE.
Mathijs Flietstra

4

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

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

문제를 해결 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; }
}

이것은 문제를 제거하지만 그 이유를 모르겠습니다!


고마워요, meataxe-한 시간이나 두 시간이 걸렸지 만 최악의 부분은 기본 클래스가 모두 설정 되었기 때문에이 문제가 있었어야한다는 것입니다. 1 년 후 멍청이가 말합니다. "이 기본 수업은 아무것도하지 않는 것 같습니다. 그냥 제거 할 것 같아요 ..."그리고 한 시간도 돌아 가지 않을 내 인생이있었습니다. 이것이 필요한 이유는 무엇입니까? EF를 더 잘 이해했으면합니다.
Wellspring

2

다른 상황에서 오류가 발생하면 다음과 같은 문제와 해결책이 있습니다.

LevledItem이라는 동일한 기본 클래스에서 파생 된 2 개의 클래스가 있습니다.

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

예, 두 번째 맵 <팀>은 맵 <스토리> 여야합니다. 그리고 그것을 알아내는 데 반나절이 걸렸습니다!


2

나는 똑같은 조건이 아니라 비슷한 문제가 있었고이 게시물을 보았습니다 . 그것이 누군가를 돕기를 바랍니다. 분명히 내 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;}

    }

1

이 오류는 다음을 수행했기 때문에 발생합니다.

  1. 데이터베이스에서 테이블의 열 이름을 변경했습니다.
  2. (사용하지 않았습니다 Update Model from database Edmx ) 데이터베이스 스키마의 변경 사항과 일치하도록 수동으로 속성 이름을 변경했습니다.
  3. 클래스의 속성 이름을 Edmx의 데이터베이스 스키마 및 모델과 동일하게 변경하기 위해 리팩토링을했습니다.

이 모든 것이 있지만이 오류가 발생했습니다

그래서 what to do

  1. Edmx에서 모델을 삭제했습니다.
  2. 마우스 오른쪽 버튼을 클릭하고 Update Model from database

이것은 모델을 재생성하고 엔티티 프레임 워크는 재생 will 하지 않습니다. give you this error

이것이 당신을 도울 수 있기를 바랍니다


1

이전 Q이지만 후손을 위해 ... 자기 참조 내비게이션 속성 ( "Parent"또는 "Children"이 동일한 유형)이 있지만 ID 속성 이름이 아닌 경우에도 발생합니다 (.NET Core 2.1). EF는 기대합니다. 즉, 클래스에 "Id"속성이 있고 이름 WorkflowBase이 관련된 관련 하위 단계 배열이 있었고 WorkflowBase존재하지 않는 "WorkflowBaseId"(이름 i 자연 / 기존의 기본값으로 선호한다고 가정합니다). 내가 명시 적으로 사용하여 구성해야했습니다 HasMany(), WithOne()그리고 HasConstraintName()어떻게 통과하는 방법을 알 수 있습니다. 그러나 몇 시간 동안 문제가 객체의 기본 키를 '로컬로'매핑하는 데 있다고 생각했는데 여러 가지 방법으로 문제를 해결하려고 시도했지만 항상 작동했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.