program story

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

inputbox 2020. 10. 16. 07:24
반응형

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


이 문제를 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. 잘못된 열 이름 오류를 중지 할 수없는 또 다른 수정 사항이 있습니까?


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

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


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

그래서...

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

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

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 .

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


가정 :

  • Table
  • OtherTable
  • OtherTable_ID

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


ㅏ)

풀다 ICollection<Table>

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

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


비)

  • 추가 OtherTableIdTable

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

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

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

...

나는 또한이 문제가 있었고 몇 가지 다른 원인이있는 것 같습니다. 나에게는 탐색 개체를 포함하는 부모 클래스에서 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;
    }
}

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

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


For me cause of this behavior was because of issue with defined mapping with Fluent API. I had 2 related types, where type A had optional type B object, and type B had many A objects.

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

I had defined mapping with fluent api like this:

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

But the problem was, that type B had navigation property List<A>, so as a result I had SQLException Invalid column name A_Id

I attached Visual Studio Debug to EF DatabaseContext.Database.Log to output generated SQL to VS Output->Debug window

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

And generated SQL had 2 relations from B table -> one with correct id and other with the A_Id

The issue for the problem was, that I did not add this B.List<A> navigation property into mapping.

So this is how in my case correct mapping had to be:

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

If you have foreign key references to the same table more than once, then you can use InverseProperty

Something like this-

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

For me (using Visual Studio 2017 and the database-first model under Entity Framework 6.1.3), the problem went away after restarting Visual Studio and Rebuilding.


In my case my seed method data was still calling a table column which had been dropped in a previous migration. Double check your mappings if you are using Automapper.


In my case the cause for this problem was a missing FOREIGN KEY constraint on a migrated database. So the existing virtual ICollection was not loaded successfully.

참고URL : https://stackoverflow.com/questions/19959256/entity-framework-invalid-column-name-id

반응형