1. ホーム
  2. asp.net-mvc-3

[解決済み] MVC3でCode First Entity Framework (4.1)を使って外部キー関係を宣言するにはどうしたらいいですか?

2022-12-10 16:21:17

質問

私は、最初の EF 4.1 のコードを使用して外部キー関係およびその他の制約を宣言する方法についてのリソースを検索していますが、あまりうまくいきません。基本的に、私はコードでデータモデルを構築し、そのモデルを照会するためにMVC3を使用しています。すべてがMVCを介して動作し、それは素晴らしいことですが(Microsoftに感謝!)、データモデル制約が必要なため、今は動作しないようにしたいのです。

たとえば、私は、外部オブジェクト (テーブル) である大量のプロパティを持つ Order オブジェクトを持っています。現在、Order を問題なく作成できますが、外部キーや外部オブジェクトを追加することはできません。MVC3 では、これを問題なく設定できます。

保存の前にコントローラクラスでオブジェクトを追加すればよいことは分かっていますが、制約関係が満たされていない場合、DbContext.SaveChanges()の呼び出しが失敗するようにしたいのです。

新情報

ということで、具体的には 例外が発生するようにしたいのです。 注文オブジェクトを保存しようとしたときに を保存しようとすると例外が発生します。これは これは、もし私が 単にオブジェクトを構成する場合 これは、ほとんどのCode First EFのドキュメントで説明されているように、オブジェクトを構成するだけでは、動作しないようです。

最新のコードです。

public class Order
{
    public int Id { get; set; }

    [ForeignKey( "Parent" )]
    public Patient Patient { get; set; }

    [ForeignKey("CertificationPeriod")]
    public CertificationPeriod CertificationPeriod { get; set; }

    [ForeignKey("Agency")]
    public Agency Agency { get; set; }

    [ForeignKey("Diagnosis")]
    public Diagnosis PrimaryDiagnosis { get; set; }

    [ForeignKey("OrderApprovalStatus")]
    public OrderApprovalStatus ApprovalStatus { get; set; }

    [ForeignKey("User")]
    public User User { get; set; }

    [ForeignKey("User")]
    public User Submitter { get; set; }

    public DateTime ApprovalDate { get; set; }
    public DateTime SubmittedDate { get; set; }
    public Boolean IsDeprecated { get; set; }
}

現在、VSで生成されたPatient用のビューにアクセスすると、このようなエラーが表示されます。

エラーメッセージ

プロパティの ForeignKeyAttribute は、タイプ 'Patient' にある Foreign Key Attribute は、タイプ 'PhysicianPortal.Models.Order'型のプロパティ'Patient'の外部キー属性が無効です。 が有効ではありません。外部キー名 'Parent' は が依存する型に見つかりませんでした。 'PhysicianPortal.Models.Order' で見つかりませんでした。そのため Name 値はコンマで区切られた外部キー・プロパティ名のリストである必要があります。 のリストでなければなりません。

Regards,

グイド

どのように解決するのですか?

もし Order クラスがある場合、モデル内の別のクラスを参照するプロパティを追加すると、例えば Customer は、そこに関係があることをEFに知らせるのに十分であるべきです。

public class Order
{
    public int ID { get; set; }

    // Some other properties

    // Foreign key to customer
    public virtual Customer Customer { get; set; }
}

を常に設定することができます。 FK 関係を明示的に設定することができます。

public class Order
{
    public int ID { get; set; }

    // Some other properties

    // Foreign key to customer
    [ForeignKey("Customer")]
    public string CustomerID { get; set; }
    public virtual Customer Customer { get; set; }
}

ForeignKeyAttribute のコンストラクタはパラメータとして文字列を取ります。これを外部キーのプロパティに置いた場合、関連するナビゲーションプロパティの名前を表します。ナビゲーションプロパティに置いた場合は、関連する外部キーの名前を表します。

これは何を意味するかというと、もしあなたが ForeignKeyAttribute の上に Customer プロパティを指定した場合、その属性は CustomerID をコンストラクタで指定します。

public string CustomerID { get; set; }
[ForeignKey("CustomerID")]
public virtual Customer Customer { get; set; }


をベースにしたEDIT 最新のコード この行のせいでそのエラーになるんですね。

[ForeignKey("Parent")]
public Patient Patient { get; set; }

EFは Parent というプロパティを探し、それを外部キーエンフォーサとして使用します。あなたは2つのことを行うことができます。

1) ForeignKeyAttribute を削除し、代わりに RequiredAttribute に置き換えて、必要なリレーションをマークします。

[Required]
public virtual Patient Patient { get; set; }

プロパティを装飾するために RequiredAttribute をつけることは、いい副次的な効果もあります。データベース内のリレーションは ON DELETE CASCADE .

また、プロパティを virtual を作成してレイジーローディングを有効にすることもお勧めします。

2) プロパティを作成します。 Parent というプロパティを作成し、外部キーとして機能させます。この場合、たとえば次のように呼び出す方がより理にかなっていると思われます。 ParentID というように呼び出すのがよいでしょう (その場合は ForeignKeyAttribute の名前も変更する必要があります)。

public int ParentID { get; set; }

私の経験では、この場合、逆にした方がうまくいきます。

[ForeignKey("Patient")]
public int ParentID { get; set; }

public virtual Patient Patient { get; set; }