7

クライアント (プレゼンテーション) とサーバー (データ/ビジネス層) の間で WCF を使用して、N 層アーキテクチャ アプリケーションを開発しています。正直なところ、WCF を介して効率的に計算されたデータを公開する方法の実際の例/情報を見つけることができません。

私の問題を説明するために、大量の取引を行う ATM マシンがあるとします。したがって、ATM クラスとトランザクション クラスの間には 1 対 N の関係があります。ATM クラスには、Location、ModelNo、Description、InstallDate などのプロパティがあり、トランザクション レコードには、Amount、DateTime、CustomerInfo、TicketPaperLength、ElectricityUsed などの情報があります。

これらのクラスを WCF で公開することは問題ではありません。問題は、基礎となるトランザクション テーブルに基づく ATM の計算フィールドが多数あることです。たとえば、クライアント アプリケーションは、ATM の計算データに基づくレポートを使用します。ATM の計算データの例としては、AverageTicketPaperLength、AverageAmount、DeviationAmount、AverageElectricity などがあります。これらの計算データは非常に多くあります。計算は、クライアント側ではなくサーバーで行う必要があります。これらのレポート定義がすべて修正されていれば、それほど大きな問題にはなりません。レポート用に個別のサービス/Poco を作成できます。計算をビジネス レイヤーに配置し、必要に応じて Poco を埋めます。

約 500 の計算されたプロパティを持つ Poco を作成できました。ここで、単一のレポートごとに 10 個のプロパティしか使用されない場合があります。しかしもちろん、すべてのエンティティに対して毎回 500 回の計算をすべて実行する必要はありません。

したがって、一般的に、エンティティの計算されたデータを WCF などを介してどのように公開するのか疑問に思っています。Entity Framework、Poco、および WCF を説明しているほとんどすべての例は、エンティティの永続フィールドのみを扱っており、非常に簡単です。

4

1 に答える 1

7

WCFを介してエンティティを公開しないでください。いくつかのDTOを作成してください。

例えば:

wcfレイヤーで-

DtoInfoForReport1 GetInfoForReport1(long atmId) { ... call BL here... } 
DtoInfoForReport2 GetInfoForReport2(long atmId) { ... call BL here... }

データレイヤー内-

AtmEntity
{
  long Id {get;set;}
  ... some properties ...
  HashSet<Transaction> AtmTransactions {get;set;}
}

オブジェクトの転送-

DtoInfoForReport1
{
  long AtmId {get;set;}
  XXX SomeCalculatedValue {get;set;}
}

BLで-

DtoInfoForReport1 CreateInfoForReport1(long atmId)
{
  var atm = YYY.GetEntity<AtmEntity>(atmId);
  return new DtoInfoForReport1
  {
    AtmId = atmId,
    SomeCalculatedValue = DoSomeCalculationOverMyAtmWithItsTransactions(atm),
  };
}

私があなたの質問を正しく理解したことを願っています。それ以外の場合はコメントします。

コメントに基づいて編集: 次のようなDTOを提案するよりも:

[DataContract]
public DtoRequestedCalculations
{
  [DataMember]
  public long AtmId {get;set;}

  [DataMember]
  public List<DtoRequestedCalculationEntry> Calculations {get;set;}
}

[DataContract]
public DtoRequestedCalculationEntry
{
  [DataMember]
  public string / long / Guid / XXX ParameterIdentifier {get;set;}

  [DataMember]
  public double/ DtoParameterCalculatedValueBase {get;set;}
}

これで、計算値が常に2倍になる場合は、基本的に実行されます。値が異なるタイプである可能性がある場合は、いくつかの基本クラス(DtoParameterCalculatedValueBase)が必要になります。これは次のようになります。

[DataContract]
[KnownType(typeof(DtoParameterDoubleCalculatedValue))]
[KnownType(typeof(DtoParameterXXXCalculatedValue))]
public DtoParameterCalculatedValueBase 
{
  ...whatever common part there may be or nth...
}

public DtoParameterDoubleCalculatedValue : DtoParameterCalculatedValueBase 
{
  [DataMember]
  public double Value {get;set;}
}

public DtoParameterXXXCalculatedValue : DtoParameterCalculatedValueBase 
{
  [DataMember]
  public XXX Value {get;set;}
}

KnowType属性に注意してください-これは、基本クラスの代わりにどのタイプが来る可能性があるかをWCFに通知します。継承されたタイプごとにこの属性を指定する必要があります(または、すでに別のストーリーであるDataContractResolverを使用します)。

WCFより:

DtoRequestedCalculations GetCalculatedValuesForAtm(long atmId, List<long / string/ Guid / XXX> valueIdentifiers);
于 2012-12-19T15:13:10.743 に答える