エンティティフレームワーク-無効な列名 '* _ID'


100

これをコードファーストとデータベースファーストEF間の問題に絞り込みましたが、どのように修正すればよいかわかりません。私はできる限り明確になるように努力しますが、正直に言うと、私自身、理解の一部が欠けています。これはEntity Framework 4.4です

Entity Frameworkが使用されているプロジェクトを継承しましたが、実際のファイルの多くが削除され、実際に戻る方法がありませんでした。私はEF(最初にデータベース)を再度追加し、プロジェクトが構築されたT4セットアップを複製しました。すべてのデータベースモデルのコードバージョンとDBContextコードファイルを生成しました。

接続文字列が "通常の" .NET接続文字列のように見える場合、無効な列名 "ProcessState_ID"が存在しないというエラーが表示されます。ProcessState_IDはコードベースにはまったく含まれていません。EDMXファイルなどには含まれていません。これは、クエリの一部の自動EF変換のようです。

接続文字列をEntity Frameworkモデルと一致させると、うまく機能します。

次に、前のコードをEntity Frameworkと一致させるために、「通常の」.NET接続文字列を維持したいと思います。

したがって、ここで2つの質問があります。1.コードで通常の接続文字列からEF接続文字列に移動するための良い方法は何ですか?2.ここに、無効な列名エラーを停止するために表示されない別の修正がありますか?


3
これは、getアクセサーのみのナビゲーションプロパティがある場合にも発生します。public virtual Person Person { get; }
ŞafakGürApr

回答:


90

ICollectionがあるかどうかを確認します。

私が理解したのは、テーブルを参照するICollectionがあり、それが理解できる列がない場合、テーブル間の接続を確立しようとする列を作成することです。これは特にICollectionで発生し、それを理解しようとする「バティ」を駆り立てました。


43
この答えは明確にするためです。なぜなら、それは私の状況に最も正確だったからです(しかし、問題が解決するまではわかりませんでした)。Tableを取得する際にOtherTable_IDに関連するエラーが発生した場合は、OtherTableモデルに移動し、そこにICollection <Table>がないことを確認してください。関係が定義されていない場合、フレームワークは、OtherTableへのFKが必要であり、生成されたSQLでこれらの追加のプロパティを作成する必要があると自動的に想定します。
LUKE

15
EFが私の4時間を無駄にした
Nitin Sawant

2
@NitinSawantあれですか?EFは私に1日4時間を費やして、重複や添付されていないレコードをすべて残しています。
ジェイコブ

@LUKEあなたのコメントは私を救った。私はあなたをとても愛しています:)
Amir Hossein Ahmadi

1
@LUKE私たちが必要とするEFヒーローではなく、必要なEFヒーロー。わたしは、あなたを愛しています。
マシューヤング

62

これは、他の2つの答えをすぐに理解しなかった(私のような)人々にとっては遅いエントリーです。

そう...

EFはPARENT TABLES KEY-REFERENCEからEXPECTED名にマップしようとしています...データベースのCHILD TABLE関係でFOREIGN KEY名が「変更または短縮された」ため、上記のメッセージが表示されます。

(この修正はEFのバージョン間で異なる場合があります)

FOR ME THE FIX WAS:
"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

@ジェリー私は外部キーを定義しています。しかし、それでもを検索しますCategory_Id。EFの異なるバージョンの修正について説明しましたか?EF 6.0を使用しています。
Ajay Aradhya 2017年

@ ajay-aradhya実際には、EFのさまざまなバージョンについてコメントしたのは、元々応答したのは囚人ゼロでした。
Jerry Benson-Montgomery

@ JerryBenson-Montgomeryは気にしないでください!私はそれを働かせました。これは、を検索する原因となった「1対1」のマッピングでした*_ID。後方参照を含めると問題なく動作しました。
Ajay Aradhya 2017

1
メタデータ部分クラスを追加してこれを修正することもできます。これにより、再生成時に修正する必要がなくなります。 [MetadataType(typeof(MetaData))] public partial class Tour { public class MetaData { [ForeignKey(nameof(TourCategory))] public virtual TourCategory TourCategory { get; set; } } }
カーターメドリン2018

39

聖なる牛-何時間も試した後、ようやくこれを理解しました。

私は最初にEF6データベースを実行していて、「不明な列の範囲」エラーについて疑問に思っていました。なんらかの理由でテーブル名の下線列名が生成され、存在しない列を見つけようとしていました。

私の場合、私のテーブルの1つに、次のような別のテーブルの同じ主キーへの2つの外部キー参照があります。

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

EFは次のようにいくつかの奇妙な列名を生成していましたOwners_AnimalID1し、Owners_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は(おそらく)期待どおりに動作し始めます。ブーム。

また、null許容列で上記を使用すると、同じエラーが発生します-の.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

14

仮定:

  • Table
  • OtherTable
  • OtherTable_ID

次のいずれかの方法を選択します。


A)

削除する ICollection<Table>

OtherTable_IDを取得するときに関連するエラーがある場合はTableOtherTableモデルに移動してICollection<Table>、そこにがないことを確認してください。関係が定義されていない場合、フレームワークは、OtherTableへのFKが必要であり、生成されたSQLでこれらの追加のプロパティを作成する必要があると自動的に想定します。

この回答のすべてのクレジットは@LUKEに属しています。上記の回答は、@ drewid回答の下での彼のコメントです。彼のコメントはとてもきれいだと思うので、答えとして書き直しました。


B)

  • 追加OtherTableIdしますTable

そして

  • 定義OtherTableIdTable中データベース

1
そんな華麗な答え!
Amir Hossein Ahmadi

この答えは確かに日ごとに素早く保存されました。そしてLUKEのおかげで、私は彼のコメントを読みました。@drewidは回答チェーンの最後で成功しましたが、それは素晴らしかったので、この状況に直面するために何が必要でしたか。
ティヴァリ

3

私の場合、次のように2つの外部キーで構成される主キーを誤って定義していました。

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出力->デバッグウィンドウに出力しました

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

生成されたSQLには、Bテーブルから2つの関係がありました。1つは正しいIDで、もう1つは A_Id

この問題の問題は、このB.List<A>ナビゲーションプロパティをマッピングに追加しなかったことです。

これが私の場合、正しいマッピングがどのようにならなければならないかです:

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

2

私の場合、この問題の原因は、移行されたデータベースでFOREIGN KEY制約が欠落していることでした。そのため、既存の仮想ICollectionは正常にロードされませんでした。


1

私にもこの問題があり、いくつかの原因があるようです。私にとっては、ナビゲーションオブジェクトを含む親クラスで、長い間ではなく誤って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

私にとっての問題は、アプリにテーブルを2回マップしたことです。

私の場合、どちらかを削除すると問題が解決します。


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 2017

0

私の場合、私のシードメソッドデータは、以前の移行で削除されたテーブル列をまだ呼び出していました。Automapperを使用している場合は、マッピングを再確認してください。


0

私の場合、私はすでにデータベース(データベースの最初)を持っています。ここのすべてのコメントのおかげで、私は私の解決策を見つけました:

テーブルには関係がなければなりませんが、列の名前は異なっていて、ForeignKey属性を追加する必要があります。

[ForeignKey( "PrestadorId")] public virtual 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.