Entity Framework-잘못된 열 이름 '* _ID'


101

이 문제를 Code First와 Database first EF 사이의 몇 가지 문제로 좁혔지만 어떻게 해결해야할지 모르겠습니다. 나는 가능한 한 명확하게하려고 노력할 것이지만 솔직히 여기에서 이해가 부족합니다. 이것은 Entity Framework 4.4입니다.

Entity Framework가 사용 된 프로젝트를 상속 받았지만 실제 파일 중 많은 부분이 실제로 돌아 가지 않고 삭제되었습니다. EF (데이터베이스 우선)를 다시 추가하고 프로젝트가 구축 된 T4 설정을 복제했습니다. 모든 데이터베이스 모델과 DBContext 코드 파일의 코드 버전을 생성했습니다.

내 연결 문자열이 "일반".NET 연결 문자열처럼 보이면 잘못된 열 이름 "ProcessState_ID"가 존재하지 않는다는 오류가 발생합니다. ProcessState_ID는 코드베이스에 전혀없고 EDMX 파일이나 다른 곳에도 없습니다. 이것은 쿼리에서 일부 자동 EF 변환으로 보입니다.

연결 문자열을 Entity Framework 모델과 일치 시키면 제대로 작동합니다.

이제 이전 코드를 Entity Framework와 일치 시키려고 시도하면서 "일반".NET 연결 문자열을 유지하고 싶습니다.

그래서 여기에 두 가지 질문이 있습니다. 1. 코드에서 일반 연결 문자열에서 EF 연결 문자열로 이동하는 좋은 방법은 무엇입니까? 2. 잘못된 열 이름 오류를 중지 할 수없는 또 다른 수정 사항이 있습니까?


3
당신은 단지 get 접근과 탐색 속성이 경우에도 발생합니다public virtual Person Person { get; }
Şafak 구르에게

답을 표시하세요
Prisoner ZERO

답변:


90

ICollection이 있는지 확인하십시오.

내가 알아 낸 것은 테이블을 참조하는 ICollection이 있고 알아낼 수있는 열이 없을 때 테이블 간의 연결을 시도 할 수 있도록 하나를 생성한다는 것입니다. 이것은 특히 ICollection에서 발생하고 그것을 알아 내려고 "배티"를 몰아 붙였습니다.


43
내 상황에 가장 정확했기 때문에이 답변을 명확히하기 위해 (그러나 내 문제를 파악할 때까지 몰랐습니다). Table을 검색 할 때 OtherTable_ID와 관련된 오류가 발생하면 OtherTable 모델로 이동하여 거기에 ICollection <Table>이 없는지 확인하십시오. 관계가 정의되지 않은 경우 프레임 워크는 OtherTable에 대한 FK가 있어야한다고 자동 가정하고 생성 된 SQL에서 이러한 추가 속성을 만듭니다.
LUKE

15
EF는 4 시간을 낭비했습니다
Nitin S

2
@NitinSawant 그게 다야? EF는 모든 중복과 첨부되지 않은 기록으로 하루에 4 시간을 낭비합니다.
Jacob

@LUKE 댓글이 저를 구했습니다. 난 당신이 너무 :) 사랑
아미르 호세인 아마디에게

1
@LUKE는 우리에게 필요한 EF 영웅이 아니라 우리에게 필요한 EF 영웅입니다. 사랑해.
Matthew Young

63

이것은 다른 두 답변을 즉시 이해하지 못한 (나와 같은) 사람들을위한 늦은 항목입니다.

그래서...

EF는 PARENT TABLES KEY-REFERENCE의 EXPECTED 이름에 매핑하려고합니다. ... 이후 FOREIGN KEY 이름이 데이터베이스 CHILD TABLE 관계에서 "변경 또는 단축"되었습니다 ... 위 메시지가 표시됩니다.

(이 수정 사항은 EF 버전마다 다를 수 있음)

나를 위해 수정 사항 :
모델에 "ForeignKey"속성 추가

public partial class Tour
{
    public Guid Id { get; set; }

    public Guid CategoryId { get; set; }

    [Required]
    [StringLength(200)]
    public string Name { get; set; }

    [StringLength(500)]
    public string Description { get; set; }

    [StringLength(50)]
    public string ShortName { get; set; }

    [StringLength(500)]
    public string TourUrl { get; set; }

    [StringLength(500)]
    public string ThumbnailUrl { get; set; }

    public bool IsActive { get; set; }

    [Required]
    [StringLength(720)]
    public string UpdatedBy { get; set; }

    [ForeignKey("CategoryId")]
    public virtual TourCategory TourCategory { get; set; }
}

4
이것은 나를 위해 일했습니다. 이 답변을 찾은 유일한 장소 인 +1입니다.
Jerry Benson-Montgomery

@Jerry 외래 키가 정의되어 있습니다. 그러나 여전히 Category_Id. 다른 버전의 EF에 대한 수정 사항에 대해 언급 했습니까? EF 6.0을 사용하고 있습니다. 채택 할 수있는 수정 사항은 무엇입니까?
아제 Aradhya

@ ajay-aradhya 사실, 원래 EF의 다른 버전에 대해 논평을 한 것은 죄수-제로 응답 한 사람이었습니다.
Jerry Benson-Montgomery

@ JerryBenson-Montgomery 신경 쓰지 마! 나는 그것을 작동시켰다. 을 (를) 검색하게 만든 '일대일'매핑이었습니다 *_ID. 역 참조를 포함하면 잘 작동했습니다.
아제 Aradhya

1
메타 데이터 부분 클래스를 추가하여이 문제를 해결할 수도 있으므로 다시 생성 할 때이 문제를 해결할 필요가 없습니다. [MetadataType(typeof(MetaData))] public partial class Tour { public class MetaData { [ForeignKey(nameof(TourCategory))] public virtual TourCategory TourCategory { get; set; } } }
Carter Medlin

40

이런 소-여러 시간 동안 노력한 끝에 마침내 이것을 알아 냈습니다.

EF6 데이터베이스를 먼저 수행하고 "확장 알 수없는 열"오류에 대해 궁금합니다. 어떤 이유로 인해 테이블 ​​이름 밑줄 열 이름을 생성하고 존재하지 않는 열을 찾으려고합니다.

제 경우에는 테이블 중 하나에 다른 테이블의 동일한 기본 키에 대한 두 개의 외래 키 참조가 있습니다.

Animals            Owners
=======            ======
AnimalID (PK)      Pet1ID    <- FK to AnimalID
                   Pet2ID    <- also FK to AnimalID

EF는 몇 가지 이상한 컬럼과 같은 이름을 생성 한 Owners_AnimalID1Owners_AnimalID2다음 자체를 깰 진행.

여기서 트릭은 이러한 혼란스러운 외래 키를 Fluent API를 사용하여 EF에 등록해야한다는 것입니다!

기본 데이터베이스 컨텍스트에서 OnModelCreating 메서드를 하고 엔터티 구성을 변경합니다. 가급적이면 EntityConfiguration클래스 를 확장하는 별도의 파일이 있지만 인라인으로 수행 할 수 있습니다.

어떤 식 으로든 다음과 같이 추가해야합니다.

public class OwnerConfiguration : EntityTypeConfiguration<Owner>
{
    public OwnerConfiguration()
    {
        HasRequired(x => x.Animals)
            .WithMany(x => x.Owners)  // Or, just .WithMany()
            .HasForeignKey(x => x.Pet1ID);
    }
}

이를 통해 EF는 예상대로 작동하기 시작할 것입니다. 팔.

또한 위의 nullable 열을 사용하는 경우 동일한 오류가 발생합니다. .HasOptional()대신 사용하십시오..HasRequired() . .


여기 저를 고비 위에 놓은 링크가 있습니다.

https://social.msdn.microsoft.com/Forums/en-US/862abdae-b63f-45f5-8a6c-0bdd6eeabfdb/getting-sqlexception-invalid-column-name-userid-from-ef4-codeonly?forum=adonetefx

그런 다음 Fluent API 문서, 특히 외래 키 예제가 도움이됩니다.

http://msdn.microsoft.com/en-us/data/jj591620.aspx

여기에 설명 된대로 키의 다른 쪽 끝에 구성을 배치 할 수도 있습니다.

http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx .

지금 제가 겪고있는 몇 가지 새로운 문제가 있지만 그게 빠진 큰 개념적 차이였습니다. 도움이 되었기를 바랍니다.


1
고마워 .. 나도 같은 문제가 있었어.
Sachin Parashar

이것은 나에게도 효과가 builder.HasOne(item => item.LogicalShipment).WithMany(s => s.Items).HasForeignKey(item => item.LogicalShipmentId).IsRequired();
있었고

14

가정 :

  • Table
  • OtherTable
  • OtherTable_ID

이제 다음 방법 중 하나를 선택하십시오.


ㅏ)

없애다 ICollection<Table>

OtherTable_ID검색 할 때 와 관련된 오류가있는 경우 모델 Table로 이동하여 거기에 OtherTable없는지 확인하십시오 ICollection<Table>. 관계가 정의되지 않은 경우 프레임 워크는 OtherTable에 대한 FK가 있어야한다고 자동 가정하고 생성 된 SQL에서 이러한 추가 속성을 만듭니다.

이 답변의 모든 크레딧은 @LUKE에 속합니다. 위의 답변은 @drewid 답변 아래의 그의 의견입니다. 나는 그의 의견이 너무 깨끗하다고 ​​생각하여 대답으로 다시 썼습니다.


비)

  • 추가 OtherTableIdTable

  • 데이터베이스 OtherTableId에서 정의Table

1
매우 유쾌한 대답!
Amir Hossein Ahmadi

이 답변은 실제로 하루에 빠르게 저장되었습니다. 그리고 LUKE 덕분에 그의 코멘트를 읽었습니다. @drewid가 답변 체인의 마지막에 만들었지 만 훌륭했고이 상황에 직면 한 대부분의 사람들에게 필요한 것이 었습니다.
Div Tiwari

3

제 경우에는 다음과 같이 두 개의 외래 키로 구성된 기본 키를 잘못 정의했습니다.

HasKey(x => x.FooId);
HasKey(x => x.BarId);

HasRequired(x => x.Foo)
    .WithMany(y => y.Foos);
HasRequired(x => x.Bar);

내가받은 오류는 "잘못된 열 이름 Bar_ID"입니다.

복합 기본 키를 올바르게 지정하면 문제가 해결되었습니다.

HasKey(x => new { x.FooId, x.BarId });

...

3

나에게이 동작의 원인은 Fluent API로 정의 된 매핑 문제 때문이었습니다. 유형 A에는 선택적 유형 B 개체가 있고 유형 B에는 많은 A 개체가있는 두 가지 관련 유형이 있습니다.

public class A 
{
    
    public int? BId {get; set;}
    public B NavigationToBProperty {get; set;}
}
public class B
{
    
    public List<A> ListOfAProperty {get; set;}
}

다음과 같이 유창한 API로 매핑을 정의했습니다.

A.HasOptional(p=> p.NavigationToBProperty).WithMany().HasForeignKey(key => key.BId);

하지만 문제는 B 유형에 탐색 속성이 List<A>있어서 결과적으로SQLException Invalid column name A_Id

Visual Studio Debug를 EF DatabaseContext.Database.Log에 연결하여 생성 된 SQL을 VS Output-> Debug 창에 출력했습니다.

db.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);

그리고 생성 된 SQL은 B 테이블에서 2 개의 관계를 가졌습니다-> 하나는 올바른 ID와 다른 하나는 A_Id

문제는이 B.List<A>탐색 속성을 매핑에 추가하지 않았다는 것입니다.

그래서 이것은 내 경우 올바른 매핑이 어떻게되어야했는지입니다.

A.HasOptional(p=> p.NavigationToBProperty).WithMany(x => x.ListOfAProperty).HasForeignKey(key => key.BId);

2

필자의 경우이 문제의 원인은 마이그레이션 된 데이터베이스에 대한 FOREIGN KEY 제약 조건이 누락 된 것입니다. 따라서 기존 가상 ICollection이 성공적으로로드되지 않았습니다.


1

나는 또한이 문제가 있었고 몇 가지 다른 원인이있는 것 같습니다. 나에게는 탐색 개체를 포함하는 부모 클래스에서 long 대신 int로 잘못 정의 된 id 속성이있었습니다. 데이터베이스의 id 필드는 C #에서 long에 해당하는 bigint로 정의되었습니다. 이로 인해 컴파일 시간 오류가 발생하지는 않았지만 OP와 동일한 런타임 오류가 발생했습니다.

// Domain model parent object
public class WidgetConfig 
{
    public WidgetConfig(long id, int stateId, long? widgetId)
    {
        Id = id;
        StateId = stateId;
        WidgetId = widgetId;
    }

    private WidgetConfig()
    {
    }

    public long Id { get; set; }

    public int StateId { get; set; }

    // Ensure this type is correct
    public long? WidgetId { get; set; } 

    public virtual Widget Widget { get; set; }
}

// Domain model object
public class Widget
{
    public Widget(long id, string name, string description)
    {
        Id = id;
        Name = name;
        Description = description;
    }

    private Widget()
    {
    }

    public long Id { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }
}

// EF mapping
public class WidgetConfigMap : EntityTypeConfiguration<WidgetConfig>
{
    public WidgetConfigMap()
    {
        HasKey(x => x.Id);
        ToTable(nameof(WidgetConfig));
        Property(x => x.Id).HasColumnName(nameof(WidgetConfig.Id)).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
        Property(x => x.StateId).HasColumnName(nameof(WidgetConfig.StateId));
        Property(x => x.WidgetId).HasColumnName(nameof(WidgetConfig.WidgetId));
    }
}   

// Service
public class WidgetsService : ServiceBase, IWidgetsService
{
    private IWidgetsRepository _repository;

    public WidgetsService(IWidgetsRepository repository)
    {
        _repository = repository;
    }

    public List<WidgetConfig> ListWithDetails()
    {
        var list = _repository.ListWithDetails();

        return new WidgetConfigMapping().ConvertModelListToDtoList(list).ToList();
    }
}   

// Repository
public class WidgetsRepository: BaseRepository<WidgetConfig, long>, IWidgetsRepository
{
    public WidgetsRepository(Context context)
        : base(context, id => widget => widget.Id == id)
    {
    }

    public IEnumerable<WidgetConfig> ListWithDetails()
    {
        var widgets = Query
            .Include(x => x.State)
            .Include(x => x.Widget);

        return widgets;
    }
}

1

나에게 문제는 내 앱에서 테이블이 두 번 매핑되었다는 것입니다. 한 번은 Code First를 통해 한 번은 Database First를 통해 한 번입니다.

둘 중 하나를 제거하면 내 경우 문제가 해결됩니다.


1

저에게는 EF의 복수화 문제로 인해 발생했습니다. "-Status"와 같이 끝나는 테이블의 경우 EF는 단일 항목이 "-Statu"라고 생각합니다. 엔티티 및 DB 테이블 이름을 "-StatusTypes"로 변경하여 수정했습니다.

이렇게하면 업데이트 될 때마다 엔티티 모델의 이름을 바꿀 필요가 없습니다.


0

동일한 테이블에 대한 외래 키 참조가 두 번 이상있는 경우 InverseProperty를 사용할 수 있습니다.

이 같은-

[InverseProperty("MyID1")]
public virtual ICollection<MyTable> set1 { get; set; }
[InverseProperty("MyID2")]
public virtual ICollection<MyTable> set2 { get; set; }

0

나를 위해 (Visual Studio 2017 및 Entity Framework 6.1.3의 데이터베이스 우선 모델 사용) Visual Studio를 다시 시작하고 다시 빌드 한 후 문제가 사라졌습니다.


원인을 설명하지 않았기 때문에 이것은 질문에 대한 확실한 대답이 아닙니다. 주석으로 넣어야합니다.
Ibo

0

제 경우에는 시드 메서드 데이터가 이전 마이그레이션에서 삭제 된 테이블 열을 여전히 호출하고있었습니다. Automapper를 사용하는 경우 매핑을 다시 확인하십시오.


0

제 경우에는 이미 데이터베이스 (Database firts)가 있습니다. 여기에 모든 의견 덕분에 내 해결책을 찾았습니다.

테이블에는 관계가 있어야하지만 열 이름이 달라야하며 ForeignKey 속성을 추가해야합니다.

[ForeignKey ( "PrestadorId")] 공개 가상 AwmPrestadoresServicios Colaboradores {get; 세트; }

즉, PRE_ID는 PK이지만 다른 테이블의 FK는 PRESTADOR_ID이면 작동합니다. 여기의 모든 의견 덕분에 내 해결책을 찾았습니다. EF는 신비한 방식으로 작동합니다.


0

동일한 테이블의 탐색 속성에이 문제가있는 경우 속성의 이름을 변경해야합니다.

예 :

Table : PERSON
Id
AncestorId (with a foreign key which references Id named Parent) 

당신은 변경해야 할 것 AncestorId입니다PersonId 합니다.

EF가 ParentIdAncestor라는 테이블을 찾을 수 없어서 키를 생성하려고하는 것 같습니다 .

편집 : 이것은 먼저 데이터베이스에 대한 수정입니다!

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