17

<RANT_MODE>

EFコードファーストのアプローチは多くの時間を節約することを目的としていますが、当面はおもちゃの例だけを見て、必要なデータベースを生成する方法を理解するために何時間も費やしました。しかし、それでもそのエウレカの瞬間を望んでいます:-)

<RANT_MODE />

質問に移りましょう!

仮想プロパティと具体的なプロパティ

EFがオブジェクトの関係をどのようにマッピングおよび取得するかを理解しようとしています。プロパティをマークする必要があるのはいつですか?マークしないのvirtualはいつですか?(public Person Owner { get; set; }vs.のようにpublic virtual Person Owner { get; set; }。)コードの数十の例で-最初に、説明の観点からあまり説明することなく、これらを交換可能に使用しているように見えることを確認しました。私が知っていることは、遅延読み込みを可能にするためにナビゲーションプロパティ(public virtual ICollection<Person> Owners { get; set; })が必要であるということvirtualです(正しい..?)が、それは非コレクションの世界にどのように適用されますか?

オブジェクト関係と外部キー

public int OwnerId { get; set; }関心のある'main'プロパティ()に加えて、外部キーフィールド()を含める必要があるかどうかについての情報を見つけることができませんでしたpublic Person Owner { get; set; }。私はそうしないように試みましたが、EFは私のテーブルに名前が付けられたint列を親切に自動追加Owner_Idし、私が何を達成しようとしているのかを理解しているようです。

コードファーストの規則(セクション「外部キー」)で、EFチームは、「関係の従属端に外部キープロパティを含めるのが一般的」であり、「コードファーストは、「」という名前のプロパティを推測するようになりました」と述べています。 (すなわち、OwnerId)[...]主キーと同じデータ型で、関係の外部キーを表します。つまり。私が両方を持っている場合、EFはそれらが関連していることを知っています。

しかし、「外部オブジェクト」自体に加えて、FKを保持するそのようなプロパティを明示的に指定することは良い習慣と見なされますか?

異物、外部キー-続き

上で述べたようにpublic Person Owner { get; set; }、オブジェクト(たとえばEvent)にのみある場合でも、テーブルにはEFによって自動的に追加されEventsた列が含まれます。Owner_Idさらに、取得すると、のプロパティにアクセスできるようになりますOwner

ただし、次のシナリオを検討してください。私は2つのクラスを持っています:

public class Account
{
    public int Id { get; set; }
    public Person Owner { get; set; }
}

public class OpenIdAccount : Account
{
    public string Identifier { get; set; }
}

TPT関連にしてほしい。これは、手動マッピングを意味します。

modelBuilder.Entity<Account>().MapHierarchy(a => new
{
    a.Id, 
    Owner_Id = a.Owner.Id
}).ToTable("Account");

modelBuilder.Entity<OpenIdAccount>().MapHierarchy(a => new
{
    a.Id,
    a.Identifier
}).ToTable("OpenIdAccount");

お気づきかもしれませんが、EFが自分のOwner_Idコラムで行うことを再現しようとしました。しかし、取得すると、myAccountInstanceFromDb.Ownerはnullになります。何故ですか?OwnerEFに魔法をかけて自分の財産を埋めるべきだとどうやって伝えるのですか?

ポインター、ポインター

上記を明確にしていただければ幸いです。答えを本当に知りたいと思うようになりましたが、EFで遊ぶのがいかに簡単かを示す別のおもちゃの例を紹介するだけの別の記事を読むことができません。とはいえ、EFの頭脳に関する最新の詳細なリファレンスがある場合は、リンクも投稿してください。

よろしくお願いします!

4

2 に答える 2

9

仮想プロパティと最終プロパティ:

これは実際には最初のコードとは関係ありません。これはEFとPOCOのトピックです。POCOがあると、ナビゲーションプロパティのEFサポートが失われ、仮想化することでオプトインできます。これにより、EFは実行時にプロキシを作成し、そのプロキシクラスのnavプロパティをオーバーライドすることでサポートを提供できます。これらのサポートは、変更通知関係の修正遅延読み込みです。

遅延読み込みは、コレクションタイプと非コレクションタイプのナビゲーションプロパティで同じように機能します。また、ナビゲーションプロパティを常に仮想としてマークすることをお勧めします

外部キー協会または独立協会

EF3.5は、アソシエーション内のFKをサポートせず、FKを非表示にします(別名Independent Associations)。EF4は、アソシエーション(別名Foreign Key Association)でFKのサポートを開始します。どちらを使用するかによって、FKプロパティを明示的に含めることも含めないこともできますが、オブジェクトを操作するための究極の柔軟性が得られるため、ナビゲーションプロパティに加えて、FKプロパティを明示的に指定することをお勧めします。

取得時に、myAccountInstanceFromDb.Ownerはnullです。何故ですか?EFに魔法をかけて、所有者のプロパティを設定するように指示するにはどうすればよいですか?

もちろん、仮想としてマークしなかったため、遅延読み込みはサポートされていませんが、明示的に読み込みを熱望したり、読み込みを延期したりすることはありませんでした。これを解決するには、仮想キーワードを使用してEF遅延読み込みを行うか、Includeメソッドを使用してオブジェクト全体がマテリアライズされたときに積極的に読み込みます。

スカラープロパティとナビゲーションプロパティ

スカラープロパティは、値が文字通りエンティティに含まれ、テーブルの列(Account.Idなど)に対応するプロパティです。
ナビゲーションプロパティは、関連するエンティティへの単なるポインタです。たとえば、アカウントエンティティには、アプリケーションがアカウントからそのアカウントを所有する所有者に移動できるようにする所有者プロパティがあります。
したがって、質問に戻ると、ナビゲーションプロパティをとして指定しvirtual Person OwnerオプションでFKプロパティをとして指定するだけで、準備は完了int OwnerIdです。

于 2010-11-26T04:54:26.157 に答える
0

プロパティを仮想としてマークすると、関連するオブジェクトが遅延呼び出しされます

外部キーフィールドを追加する必要はありませんpublicPersonOwner {get; セットする; }は外部キーマッピングを追加します

于 2010-11-26T01:39:11.570 に答える