5

私はコードファーストアプローチを使用しており、次のモデルがあります。

public class Person
{
    public int ID {get; set;}
    public string Name {get; set;}

    public int CurrentStationID {get; set;}
    public virtual Station CurrentStation {get; set;}

    public int CurrentTransportationID {get; set;}
    public virtual Transportation CurrentTransporation {get; set;}
}

そして、私のコントローラーの次のコード:

Models.Person model = myDBContext.Persons
                        .Include("CurrentStation")
                        .Include("CurrentTransportation")
                        .Where(p => p.ID == 1)
                        .FirstOrDefault();

DBテーブル"persons"に(1、 "Testname"、0、0)の行が存在する場合でも、"model"はNULLになります。

上記は、を使用してSQLステートメントを生成します[...] INNER JOIN stations AS [...] LEFT JOIN transportations [...]。基になるテーブル/タイプが何であるか、またはそれらを指定する順序に関係なく、すべてのモデルについて、最初のナビゲーションプロパティに対して常に内部結合を実行します。これは常に最初のInclude()です。

「CurrentStation」がデータベースに存在する必要がないため、すべての内部結合ではなく左側結合が必要です

なぜEFはこれを行うのですか?わかりませんが、理解したいです。どのプロパティにも[必須]属性を指定していませんが、指定した場合と同じように動作します。

残念ながら、[Optional]属性はなく、OnModelCreate-overrideを介して「HasOptional()」を実行することは私にとってオプションではありません。

4

2 に答える 2

7

私が間違っていない場合、プロパティをオプションにするか、データベースの意味でnull許容にするためには、プロパティをnull許容にする必要があります。したがって、CurrentStationIdプロパティの場合は、次のように宣言してみてください。

 public int? CurrentStationId {get;set;}

更新 この投稿はあなたの状況に役立つかもしれません。

于 2012-06-15T17:10:28.133 に答える
2

そもそもあなたを悩ませるべきなのは、データベースの設計です。あなたが持つことができCurrentStationId = 0、同時にそれがない場合StationId = 0それはあなたのデータベースが参照整合性を使用していないことを意味します。

EFを使用するには、参照整合性が前提条件です。エンティティ間の関係が必要な場合は、そのような関係がデータベースに存在し、参照制約が適用されていることを確認してください。そうでない場合は、とにかく他の多くの予期しない動作が発生すると思います。

Station唯一の正しいアプローチなしで人を持つことができる場合は、CurrentStationId列とプロパティをnull許容にすることです。EFは、データベースに制約が適用されていると考えているため(オフにすることはできません)、INNER JOINを使用でき、FKをnull許容にすることなく変更することはできません。データベースでこれを変更できない場合は、EFでリレーションをマップしないでください。または、EFを使用しない方がよいでしょう。

データベースを制御できる場合、さらにこの方法で設計した場合は、コーディングを停止してホワイトボードに戻り、設計について考え、データベース設計のベストプラクティスに従うように改善する必要があります。それはあなたが将来持つことができる多くの問題をあなたに救うでしょう。

于 2012-06-16T15:52:10.590 に答える