2

私は(契約上の制約のために、不自然で過度に単純化された)データモデルを持っています。これは次のようになります。

public class ProvisionalData
{
    public int ProvisionalDataID { get; set; }
    public string Data { get; set; }

    public Lot Lot { get; set; }
}

public class Destination 
{
    public int DestinationID { get; set; }
    public string Name { get; set; }
}

public class LotDestination
{
    public int LotDestinationID { get; set; }
    public int DestinationID { get; set; }
    public DateTime Month { get; set; }

    public Destination Destination { get; set; }
}

public class Lot
{
    public int LotID { get; set; }
    public int ProvisionalDataID { get; set; }
    public int LotDestinationID { get; set; }


    public ProvisionalData ProvisionalData { get; set; }
    public LotDestination LotDestination { get; set; }
}

Lot から ProvisionalData への関係は、両側で 1 対 1 である必要があります。これはモデル全体ではなく、ドメインも問題ではないことに注意してください。問題は、1 対 1 の関係を構成することです。

1 対 1 のマッピングの流暢な構成に関連するもの:

public class LotConfig : EntityTypeConfiguration<Lot>
{
    public LotConfig()
    {
        ToTable("Lot");
        HasKey(x => x.LotID);

        HasRequired(x => x.ProvisionalData)
            .WithRequiredDependent(x => x.Lot)
            .WillCascadeOnDelete(true);
    }
}


public class ProvisionalDataConfig : EntityTypeConfiguration<ProvisionalData>
{
    public ProvisionalDataConfig()
    {
        ToTable("ProvisionalData");
        HasKey(x => x.ProvisionalDataID);
    }
}

表示されているその他の関係は実際にセットアップされています。それらが私のコンテキストで構成されていること、およびすべての IDbSet が存在し、正しく機能していることを確認しました。実際、ナビゲーション プロパティの一部の ProvisionalData エンティティが次のクエリによって設定されないことを除いて、このセットアップではすべてが "機能" します。

var lotDestination = db.lotDestinations
    .Where(x => x.DestinationId == destinationId && x.Month == month)
    .Include(x => x.Lots)
    .Include("Lots.ProvisionalData")
    .Include(x => x.Destination)
    .SingleOrDefault();    

私の実際のデータセットでは、このクエリは 30 ロットの目的地を返します。これらのロットのうち 16 ロットには、ProvisionalData ナビゲーション プロパティが読み込まれています。14 しません。各 Lot と を手動でループしても、この問題は解決しませんdb.Entry(lot).Reference(ProvisionalData).Load()。これらのエントリを調べると、30 個すべてtrue.IsLoaded. クエリ.Includesは想定どおりに動作しているように見えますが、理解できない理由で一部のエンティティが戻ってこないのです。あまりにも長い間見つめていたために見えない単純なものであることを願っています.

ただし、関係を (既存のデータベースの制約を無視して) 1 対多に変更すると、ProvisionalData エンティティは次のようになります。

public class ProvisionalData
{
public int ProvisionalDataID { get; set; }
public string Data { get; set; }

public IList<Lot> Lots { get; set; }
}

そして、次のような新しいロット構成:

public class LotConfig : EntityTypeConfiguration<Lot>
{
    public LotConfig()
    {
        ToTable("Lot");
        HasKey(x => x.LotID);

        HasRequired(x => x.ProvisionalData)
            .WithMany(x => x.Lots)
            .HasForeignKey(x => x.ProvisionalDataID);
    }
}

すべてが問題なく動作します。ここでの唯一の欠点は、これがデータベースの真の制約を反映していないことです。そのため、技術的には複数のロットを同じ ProvisionalData に追加しようとすると、保存しようとすると壊れてしまいます。これを自分で防ぐロジックを組み込むことはできますが、Entity Framework で表現できないのはなぜでしょうか? 私の設定は間違っていますか?

また興味深いことに、上記のクエリをこのダム バージョンに切り替えてテストすると (1 対 1 のマッピングは EF に残っています):

var quota = db.Lots
    .Where(l => l.LotDestination.DestinationID == destinationId && l.LotDestination.Month == m)
    .Include(x => x.ProvisionalData)
    .Include(x => x.LotDestination)
    .Include(x => x.LotDestination.Destination)
    .Select(x => x.LotDestination)
    .FirstOrDefault();

すべての暫定データが戻ってきますが、一部の宛先はそうではありません。これは、1 対 1 で複数レベルのナビゲーション プロパティを含めることに関係があることを示唆しています。他の誰かが以前にこの動作を経験したことがありますか?

4

2 に答える 2