[entity-framework] 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");
}

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

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


답변

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

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

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


답변

나는 똑같은 조건이 아니라 비슷한 문제가 있었고이 게시물을 보았습니다 . 그것이 누군가를 돕기를 바랍니다. 분명히 내 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. 데이터베이스에서 테이블의 열 이름을 변경했습니다.
  2. (사용하지 않았습니다 Update Model from database Edmx ) 데이터베이스 스키마의 변경 사항과 일치하도록 수동으로 속성 이름을 변경했습니다.
  3. 클래스의 속성 이름을 Edmx의 데이터베이스 스키마 및 모델과 동일하게 변경하기 위해 리팩토링을했습니다.

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

그래서 what to do

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

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

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