2017-01-19 2 views
2

私はEntity Frameworkをかなり新しく使用しています。最後に を費やしました。 日)単純な関係で働く。人、家、ガレージEntity Frameworkゼロまたは1から0へのリレーションシップを0から1にすることはできません。

  • Aパーソンどれか複数(0..N)住宅とガレージが
  • Aハウスが持つことはできませんことができます(0..1)A:

    は、私は三つのクラスを持っていますガレージと一人だけに

  • を属している必要があり
  • Aガレージは、したがって、(0..1)を持つことができるハウスと一人だけに属している必要があります
  • ではありませんガレージ
  • と住宅と住宅がないとガレージがあります。ガレージやホーがありません。私はそれを持っていると思います。

これまでのところ、私は10の異なる文書を読んでいました。注釈を使って解決しようとしましたが、この流暢なAPIを組み込む必要があるようです。

私が一番遠いのは、家とガレージを人に関連付けることですが、お互いには関連付けないことです。今私は関係の原則的な終わりを定義しなければならなくなってしまいました。私はそれが何をすべきか理解していません。

は今、私は依存操作のための有効な順序を決定することができません

を取得します。依存関係は、外部キー制約、モデル要件、またはストア生成値のために存在する可能性があります。

さまざまなエラーの弾幕を解決しようとしています。

私はPHPの年齢のためにこれらのような関係をマニュアルで作成しています。物事をより簡単にするためのより大きなフレームワークでデータベースの作業を行うのは今回が初めてですが、これまでのところ私はDatabaseReaderからオブジェクトを作成することで多くの成功を収めていました。

私の論理的な観点からは、3つのクラス/テーブル間の関係は本当にシンプルであるべきですが、私は類似の関係の例を見つけることができず、ちょうどうまく動作するようにはなりません。

だから私の質問は以下のとおりです。

  • は、それが最初のコードで設計するので、難しいことを、ゼロまたは1の関係本当に特別にゼロまたは-1ですか?
  • GarageIdのHouseテーブルをフィルタリングして対応するHouseを見つけることができるため、GarageテーブルにHouseテーブルの外部キーは必要ありませんか?私はコード内でHouseのルックアップを実装しようとしましたが、データベースプロパティではなくなったのでLINQが壊れていることに気付きました。
  • 私はannotationsとFluent APIを試しました.0.1から0..1(または実際には、その他の)関係の上位の例は、正しく見えなかったので、modelBuilderのフィールドをスワップしようとしましたDBの中で... DBがちょっと大丈夫だが、コードがまだ動作しないようなところに達するまで。それ以外に何ができますか?
  • たぶん私はすべてのDBのものを間違ってやってきましたし、これらのような関係は関係するすべての人にとって不健康です。その場合、私は上記のPerson-House-Garageの関係を再現しようと提案しますか?私が住宅とガレージの間に押し込んで仕事をすることができるヘルパークラスはありますか?

私はデモプロジェクト用意していますhttps://github.com/Zaphox/DatabaseTest
それは三つのクラス、コンテキストと正常に完了しなければならない関係のテストが含まれています(ただし、いませんが)。

この問題の解決につながるすべてのヘルプとヒントをお寄せいただきありがとうございます。

Z.

アップデート1

私は、円形の関係がEFでエラーが発生し、このような参照を作成するだけでは不可能だと思われるが、でも0..1に気づいすべての提案をしようとした後、 0..1自己参照は機能していないようです。

私は少なくとも仕事をさせるハックを実装しましたが、それは恐ろしいことですし、もっと良い方法があることを誰かに教えてもらいたいです。

  1. のみ住宅は、ガレージへの参照を持っていない、その逆
  2. 別のクエリが必要とされてガレージに属するハウスを取得する(db.Buildings.OfType<House>().Where(h => h.Garage.Id == myGarage.Id).First()

はまた、私はNotMappedハウスフィールドを追加することを考えましたガレージでは家自体のルックアップを行いますが、それは他のクエリと干渉するため、有効なオプションでもありません。

私を大いに悩ますものは、自己参照などに関する多くの記事がありますが、1対nの関係のみです。 1対1、または0..1対0..1の関係を作る試みは常に失敗し、EFは「注文」を把握できません。

EFはGarageId FKをHouseテーブルに、HouseId FKをGarageテーブルに入れなければならないと思いますが、それはナンセンスです。 HouseテーブルにはGarageIdが必要です。これは後方参照として使用できます。このコードを実装することはできますが、EFクエリと互換性がなく、通常は2つのクエリを同時に実行できないため、他の実行クエリと干渉します。

GitHubのデモプロジェクトは現在のバージョンで更新されていますが、Garageに属するHouseを検索するたびに、多くの追加クエリが必要になります。

+0

'House'や' Garage'クラスには、人や他の 'House' /' Garage'へのリンク以外の属性がありますか? –

+0

はい、これらのクラスはすべて空ですので、関係を理解することができますが、後で属性(名前、住所、サイズ)、リンク(清掃会社やその他の連絡先、HVACドキュメントへのリンク、 ..)。 –

+0

明らかに、問題は「ガレージ」と「ハウス」の関係です。どちらもオプションであり、どちらもプリンシパル/依存関係ではありません。私はEFがそのような関連をサポートしていないと思います。多対多の関係を使用することを提案することができます(私はそれがあなたが必要とするものではないと知っていますが、ガレージとガレージなし家)。 –

答えて

2

のようなものと同じタイプでないことを強制することができます。

私はHouseテーブルにGarageIdが必要です。これは後方参照として使用できます。実際に

これは、あなたが(FK列名がGarage_Idある唯一の違いで)HouseクラスにのみGarageナビゲーションプロパティを入れたときに、デフォルトでは何が起こるかです。これは単方向結合と呼ばれます。このようなセットアップでは、EFはHouseを従属とみなし、Garageをプリンシパルとし、両方をオプションにします。重要な部分は、に依存するテーブルにFK列が作成されていることです。

これはあなたのテストプロジェクトに現在あるものであり、動作します。あなたはGarageクラスにHouseプロパティを追加することによって、関連の双方向を作る際に問題が発生:

public class House 
{ 
    public int Id { get; set; } 
    public Garage Garage { get; set; } 
    public string Style { get; set; } 
} 

public class Garage 
{ 
    public int Id { get; set; } 
    public House House { get; set; } 
    public int Size { get; set; } 
} 

この場合、EFには十分な情報がどのようなあなたの意図であるので、あなたはその情報を提供する必要がありません。 GarageId FKがHouseのテーブルにあることを覚えておいてください。追加する必要があるFluentの設定はここにあります(Mapの部分は省略可能です - スキップするとFKの列は現在のプロジェクトのようにGarage_Idとなります):

modelBuilder.Entity<House>() 
    .HasOptional(e => e.Garage) 
    .WithOptionalDependent(e => e.House) 
    .Map(m => m.MapKey("GarageId")); 

とすべてが期待どおりに動作します。

+0

本当にそうです。私は、常に私のためにエラーに終わった非常に似たようなコードをたくさん試してみました、私はどこかでミスを犯したに違いないと思います。あなたの例は完璧にうまくいく、ありがとう! –

+0

あなたは間違いを犯す唯一の人ではありません:)問題は、EFが時には奇妙な行動につながるいくつかのデフォルト仮定をしていることです。たとえば、 'House' navプロパティを追加する前に、' .WithOptionalDependent() '(引数がないことに注意してください)という唯一の違いを持っ​​て、同じ流暢な設定を使いました。その後、navプロパティを追加しましたが、configの更新を忘れてしまい、動作が停止しました。データベースを見て、私は 'House_Id' FKを' Garage'テーブルに静かに追加したことに気付きました! configを修正すると問題が解決しました。 –

+0

これらの関係には非常に注意し、常に生成されたテーブルをチェックする必要があります。乾杯。 –

1

エンティティフレームワークでは、プリンシパルが明確でないリレーションシップが嫌いです。この場合、いずれかのエンティティが他のエンティティなしで存在する可能性があるため、どちらも他方に依存しません。

抽象クラスBuildingHouseGarageの両方から派生するようにモデルを再設計することをお勧めします。 PersonBuildingにリンクすることができ、具体的なタイプの「ハウス」とGarageには、関連付けのためのBuildingへのリンクがあります。

例:

public abstract class Building 
{ 
    public Person Person { Get; Set; } 

    public Building Building { Get; Set; } 
} 

public class House : Building 
{ 
    // Other House properties 
} 

public class Garage : Building 
{ 
    // Other Garage properties 
} 

そして、ビジネスロジックであなたは、関連する建物はどうやら問題はHouseGarageとの関係であるthis.GetType() != Building.GetType()

+0

優れたアイデアは、私は今すぐ実装しようとします。 –

+0

残念ながら 'public Building ConnectedBuilding {get;セット; } 'も' '依存する操作のための有効な順序を決定できません.''、自己参照する際にどのように順序を定義しますか? –

+0

また、 'House'にオプションのGarageを定義しようとしました。その一方で、' DatabaseTest.Garage 'と' DatabaseTest.House 'の間の関連の主な終点を特定できませんでした。 すぐに'Building'を基にしたクラスのいずれかに' Building'派生のクラスを定義すると、これは前と同じ問題を引き起こします。順序を見つけ出すことに問題があったり、元の終わりをまったく見つけることができません。それは、EFがこのような関係の問題を抱えていることを私に奇妙なものにしています。 –

関連する問題