2012-12-19 5 views
7

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

私の問題を説明するには、多くのトランザクションを持つATMマシンがあると言います。したがって、ATMクラスとトランザクションクラスの間に1-Nの関係があります。 ATMクラスにはLocation、ModelNo、Description、InstallDateなどのプロパティがあり、トランザクションレコードにはAmount、DateTime、CustomerInfo、TicketPaperLength、ElectricityUsedなどの情報があります。

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

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

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

答えて

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;} 
} 

転送オブジェクト - BLに

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

-

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

私はあなたの質問を正しく受け取ります。それ以外はコメント。あなたの計算された値は、常にそれは基本的に行ってい倍増であれば今

[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;} 
} 

:私はこのようなのDTOを示唆するだろうより :

編集コメントに基づきます。自分の価値観があることや、異なる種類可能性がある場合、あなたは、いくつかの基本クラスが必要になります - DtoParameterCalculatedValueBase、このようなSTHです:

[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;} 
} 

KnownType属性を注意してください - それは、基本クラスの代わりに来るかもしれない何種類WCFに指示します。継承された型ごとにこの属性を指定する必要があります(または既に別の記事であるDataContractResolverを使用します)。

WCFに比べ

:一般的に

DtoRequestedCalculations GetCalculatedValuesForAtm(long atmId, List<long/string/ Guid/XXX> valueIdentifiers); 
+0

私は、DTOのを使用して同意します。あなたの説明は私の問題をかなり指摘しています。問題は、私が、例えば、との正確な定義を知らないことです。フォアハンドでGetInfoForReport1とGetInfoForReport2。他のレポートもあるかもしれませんし、ユーザーが要求するデータがわかりません。エンドユーザは、ATMからいくつかの計算フィールドを選択し、レポートを要求する。可能な組み合わせのフィールドごとにDTOを作成するには少し余裕があります – Erik

+0

答えが –

+0

に変更されました。次にWCF GetCalculatedValuesForAtmでvalueIdentifiersが対応する計算を参照していますか?しかし、これでも高いAverageElectricityを持つATMのリストが必要な場合は、すべてのATMを繰り返し処理し、各ATMのAverageElectricityについてこのWCFを呼び出す必要があります。 (ちょうど私が1台のATMのレポートの代わりにすべてのATMの報告書を意味していたことを認識しています)元の質問では言及されていませんでした。 – Erik

関連する問題