0

Entity Framework 5.0 を使用しています。

シナリオ

「組織」には「クライアント」のリストと「期間」のリストと「CurrentPeriodID」があります。各期間の開始時に、「クライアント」の一部またはすべてがその「期間」に関連付けられています。リンクテーブルとこれは正常に機能するため、「組織->期間->クライアント」を実行すると、「期間」の「クライアント」のリストが取得されます。

次に、「期間」の「クライアント」にいくつかのオブジェクト ( 「アクティビティ」 )を追加する必要があるため、「組織 -> 期間 -> クライアント - > アクティブ化」を取得します。 「クライアント」「アクティビティ」に追加する必要がある他のナビゲーション プロパティと、それらすべてを「期間」に関連付ける必要があります。(可能であれば) 「組織->期間-」も実行できる必要があります。活動」 .

質問

「Organisation->Period-Client」の「Activities」を実装する最良の方法は何でしょうか。コードファーストのリバースエンジニアリングなどは気にしません。「Organisation」オブジェクトの作成についても「Organisation」オブジェクトに保存されている「CurrentPeriodID」値を使用して、現在の「Period」オブジェクトをロードします。

ありがとう

4

1 に答える 1

0

私には、これは を接続する追加のエンティティが必要なように思えますが、それをPeriodClient呼びActivityましょうClientActivityInPeriod。このエンティティ (および対応するテーブル) には、3 つの外部キーと 3 つの参照があります (コレクションはありません)。その組み合わせは一意でなければならないため、そのエンティティの主キーを3つの外部キーの構成にするでしょう。次のようになります (Code-First スタイルで):

public class ClientActivityInPeriod
{
    [Key, ForeignKey("Period"), Column(Order = 1)]
    public int PeriodId { get; set; }

    [Key, ForeignKey("Client"), Column(Order = 2)]
    public int ClientId { get; set; }

    [Key, ForeignKey("Activity"), Column(Order = 3)]
    public int ActivityId { get; set; }

    public Period Period { get; set; }
    public Client Client { get; set; }
    public Activity Activity { get; set; }
}

3 つの外部キーすべてが必要です(プロパティは null 許容ではないため)。

PeriodClientおよびActivityこのエンティティを参照するコレクションを持つことができます (ただし、そうする必要はありません)。たとえば、Period次のようになります。

public class Period
{
    [Key]
    public int PeriodId { get; set; }

    public ICollection<ClientActivityInPeriod> ClientActivities { get; set; }
}

からの外部キー、またはとの間の多対多のリンク テーブルが必要になるため、特定の期間にアクティビティがあるすべてのクライアントを含むClientsinのコレクションのようなナビゲーション プロパティを持つことはできません。外部キーまたはリンク テーブルは、クライアントにアクティビティがある場合にのみ入力されます。EF もデータベースも、このようなビジネス ロジックでは役に立ちません。これをプログラムして、アクティビティが期間に追加または削除された場合に関係が正しく更新されるようにする必要がありました。これはエラーが発生しやすく、データの一貫性を損なうリスクになります。PeriodClientPeriodClientPeriodPeriod

1代わりに、次のように、ナビゲーション プロパティではなくクエリによって、特定の期間にアクティビティがあるクライアントをフェッチします。

var clientsWithActivitiesInPeriod1 = context.Periods
    .Where(p => p.PeriodId == 1)
    .SelectMany(p => p.ClientActivities.Select(ca => ca.Client))
    .Distinct()
    .ToList();
于 2013-05-06T18:43:14.487 に答える