0

私はEFの初心者です。http://msdn.microsoft.com/en-us/data/gg193958.aspxを読みましたが、まだ混乱しています。

既存のデータベースがあり、CodeFirstモデルを作成しています。op_code Char(6)主キーを持つOperatorsテーブルがあります。Operatorクラスでは、OperatorCodeという名前を付けました。

[Key]
[Column("op_code",TypeName = "char")]
[DisplayName("Operator")]
public virtual string OperatorCode { get; set; }

私のテーブルのいくつかには、EnteredByがあり、いくつかのModifiedBy列には、op_codeのFKがあります。

たとえば、Clientsテーブルには、これらのフィールドの両方があります。

そこで、下部のOperatorクラスに追加しました。

[InverseProperty("EnteredBy")]
public virtual ICollection<Client> ClientsEnteredBy { get; set; }

[InverseProperty("ModifiedBy")]
public virtual ICollection<Client> ClientsUpdatedBy { get; set; }

そして、Clientクラスに以下を追加しました。

public virtual Operator EnteredBy { get; set; }
public virtual Operator ModifiedBy { get; set; }

EnteredBy_OperatorCode列とModifiedBy_OperatorCode列に関する実行時エラーが発生します。

EFに列名を知らせるには、何を修正/追加する必要がありますか?

前もって感謝します。

4

1 に答える 1

1

データベース内の外部列名が、FK名のデフォルトの規則である。と一致しませんNavigationPropertyName_PrimaryKeyNameinTargetClass。ナビゲーションプロパティが呼び出され、主キープロパティが呼び出されるためEnteredByModifiedByEFOperatorCodeは、前述の規則に従って、外部キー列として期待しEnteredBy_OperatorCodeますModifiedBy_OperatorCode。しかし、それらはデータベースに存在しないため、例外が発生します。EnteredBy代わりに、FK列はとModifiedByです。

したがって、問題を修正するには、規則をオーバーライドする必要があります。

モデルにFKプロパティがない場合は、FluentAPIを使用します。

modelBuilder.Entity<Operator>()
    .HasMany(o => o.ClientsEnteredBy)
    .WithRequired(c => c.EnteredBy)    // or HasOptional
    .Map(m => m.MapKey("EnteredBy"));  // mapping for the FK column name

modelBuilder.Entity<Operator>()
    .HasMany(o => o.ClientsUpdatedBy)
    .WithRequired(c => c.ModifiedBy)    // or HasOptional
    .Map(m => m.MapKey("ModifiedBy"));  // mapping for the FK column name

(このマッピングを使用すると、InverseProperty属性を削除できます。)

別のアプローチは、FKをモデルのプロパティとして公開することです。ナビゲーションプロパティの名前を変更し、FKプロパティにそれらの名前を使用します。その後、データ注釈を使用してマッピングが可能になります。

Clientクラスで:

[ForeignKey("EnteredByOperator")]
public string EnteredBy { get; set; }

[InverseProperty("ClientsEnteredBy")]
public virtual Operator EnteredByOperator { get; set; }

[ForeignKey("ModifiedByOperator")]
public string ModifiedBy { get; set; }

[InverseProperty("ClientsUpdatedBy")]
public virtual Operator ModifiedByOperator { get; set; }

そして、クラスのInverseProperty属性を削除します。Operator

データ注釈の代わりに、FluentAPIを使用することもできます。

modelBuilder.Entity<Operator>()
    .HasMany(o => o.ClientsEnteredBy)
    .WithRequired(c => c.EnteredByOperator)    // or HasOptional
    .HasForeignKey(c => c.EnteredBy);

modelBuilder.Entity<Operator>()
    .HasMany(o => o.ClientsUpdatedBy)
    .WithRequired(c => c.ModifiedByOperator)    // or HasOptional
    .HasForeignKey(c => c.ModifiedBy);

両方の関係が必要な場合は、少なくとも1つの関係のカスケード削除を無効にする必要があります(.WillCascadeOnDelete(false)いずれかのマッピングの最後に追加します)。そうしないと、SQL Serverは、テーブル間の複数のカスケード削除パスが許可されないというエラーをスローします。

ほとんどの場合、操作が簡単なので、「代替アプローチ」(プロパティとして外部キーを公開する)を使用することをお勧めします。

于 2012-09-12T20:36:51.827 に答える