0

アプリケーションの DAL 層と BL 層を実装しています。WCF サービスとしてホストされ、EF 4 が ORM として使用されます。ロールベースのセキュリティレイヤーと、特定のロールによってオブジェクトの一部のみを更新できるビジネスルールがあります。

問題の簡単な例を次に示します。

このような DTO があります。

MainType
{
    public Guid ID { get; set; }
    public String DoctorField1 { get; set; }
    public String DoctorField2 { get; set; }
    public String NurseField1 { get; set; }
    public String NurseField2 { get; set; }
    public DateTime Created {get; set;}
    public DateTime Updated {get; set;}
    public Guid LastUpdateBy {get; set;}

    public List<DetailsType> Details { get; set; }
}

DetailsType
{
    public Guid MainTypeID { get; set; }
    public Guid SomeIdentityID { get; set; }

    public String DoctorDetail { get; set; }
    public String NurseDetail { get; set; }
    public DateTime Created {get; set;}
    public DateTime Updated {get; set;}
    public Guid LastUpdateBy {get; set;}
}

このエンティティは、同じフィールドを持つ対応する DB テーブルにマップされます。

  • MainType の ID フィールドは主キーです。
  • DetailsType の MainTypeID は MainType テーブルへの外部キーです。
  • DetailsType の SomeIdentityID は、このサンプルにとって重要ではない他のエンティティへの FK です。
  • MainTypeID SomeIdentityID は、DetailsType テーブルの複雑な主キーです。

このようなオブジェクト (1 つのメインとリストの詳細) のグラフがあり、更新操作を実行するユーザーの役割を決定しました。私の仕事は:

  • 現在のユーザーが医師の役割を持っている場合 - メイン オブジェクトとすべての詳細オブジェクトの医師フィールドを更新し、新しい詳細オブジェクトを挿入します。
  • 現在のユーザーに看護師の役割がある場合 - メイン オブジェクトとすべての詳細オブジェクトの看護師フィールドを更新します。
  • 現在の日付を更新済みフィールドに保存
  • 現在のユーザー ID を LastUpdateBy フィールドに保存する
  • Created フィールドや、このロールによって更新されないその他のフィールドは変更しないでください。

たとえば、ロール Doctor を持つユーザーがいる場合、次のようにする必要があります。

  • MainObject の DoctorField1、DoctorField2、Updated、LastUpdateBy を更新します。
  • すべての詳細オブジェクトで DoctorDetail、Updated、LastUpdateBy を更新する
  • 他のフィールドは変更しないでください。

現在、MainObject の完全なグラフを読み取り、必要な変更を加えて DB に保存する実装があります。このソリューションは動作が遅すぎるため、改善する方法を見つける必要があります。現在、RAW SQLでそれを行う方法を明確に知っていますが、他に何も役に立たない場合に備えて、これが私の解決策になります。

必要なフィールドのみを更新し、別のフィールドを無視するように Entity Framework を作成するにはどうすればよいですか。

String フィールドの ApplyOriginalValues メソッドと ApplyCurrentValues メソッドで、いくつかの成功した結果が得られました。アイデアは、両方のオブジェクトのプロパティに架空の値を割り当てることでした。変更の保存中に変更されていないプロパティ。ただし、このトリックは Boolean、Int32、および Decimal 値では機能しません。すべてのオブジェクトに対して単純なアプローチを使用する必要があります。

この問題に関するアイデアや考えをいただければ幸いです。

4

1 に答える 1

1

このような特定の要件がある場合は、ユーザーが変更できないフィールドを受け入れないように WCF サービスを変更することから始める必要があります。これは、次の 2 つの単純な DTO につながります。

public class MainTypeUpdateDto
{    
    public Guid ID { get; set; }
    public String Field1 { get; set; }
    public String Field2 { get; set; }
    public List<DetailsTypeUpdateDto> Details { get; set; }
}

public class DetailsTypeUpdateDto
{
    public Guid MainTypeID { get; set; }
    public Guid SomeIdentityID { get; set; }
    public String Detail { get; set; }
}

他のすべてのフィールドは更新できないか、サーバー側のロジックで処理する必要があります。

dto を受け取ったら、それらを実際のエンティティ オブジェクトにマップし直すことができます。ユーザーの役割に基づいて、どのフィールドと詳細を設定する必要があるかがわかります。必要なフィールドのみを保存するように EF を強制するには、次の 2 つのオプションがあります。

  • まずMainType、関連する詳細を含むオブジェクト グラフを作成します。MainTypeこれらのエンティティに ID のみを設定し、エンティティをコンテキストに添付します。その後、更新可能なすべてのフィールドを現在の値に設定します。エンティティの状態を変更しないでください。
  • MainType and all related details and set all Ids and all updatable fields. After that attachMainType` エンティティを使用してオブジェクト グラフをコンテキストに作成し、変更された各プロパティの状態を (各エンティティで)手動で設定します。

ユーザーが詳細を削除または追加できる場合は、追加のロジックが必要になる場合があります。

于 2011-12-04T15:39:27.633 に答える