1

この質問は私が解決策を見つけようとしている1年以来のように私を眠らせませんが...それでも私の心には何も起こりませんでした。これは非常に一般的な問題だと思うので、おそらくあなたは私を助けることができます。

私はn層のアプリケーションを持っています:プレゼンテーション層、ビジネスロジック層、モデル層。簡単にするために、私のアプリケーションのプレゼンテーション層に、ユーザーが顧客を検索できるフォームが含まれているとします。これで、ユーザーはUIを介してフィルターに入力し、ボタンをクリックします。何かが起こり、リクエストはプレゼンテーション層に到着し、のようなメソッドになりCustomerSearch(CustomerFilter myFilter)ます。このビジネスロジックレイヤーにより、シンプルになりました。モデルにクエリを作成し、結果を取得します。

さて、質問:データのロードの問題にどのように直面しますか?つまり、ビジネスロジック層は、その特定のメソッドがそのフォームだけで呼び出されることを認識していません。したがって、リクエストフォームに必要なのはCustomerオブジェクトだけなのか、LinkedOrderエンティティを持つCustomerオブジェクトだけなのかはわかりません。

私はもっ​​とよく説明しようとしています。私たちのフォームは、名前で検索している顧客をリストしたいだけです。それは注文とは何の関係もありません。したがって、ビジネスロジッククエリは次のようになります。

(from c in ctx.CustomerSet
where c.Name.Contains(strQry) select c).ToList();

現在、これは正しく機能しています。2日後、上司から、他の顧客と同じように顧客を検索できるフォームを追加するように求められました。各顧客が作成した注文の総数を表示する必要があります。次に、そのクエリを再利用して、注文を添付(含む)してそれを取り戻すロジックを追加したいと思います。

このリクエストをどのように処理しますか?

これが私が今から持っていた最高の(私が思う)アイデアです。ご意見をお聞かせください。BLLのCustomerSearchメソッドはクエリを直接作成しませんが、次のようなObjectQueryを構成するプライベート拡張メソッドを通過します。

private ObjectQuery<Customer> SearchCustomers(this ObjectQuery<Customer> qry, CustomerFilter myFilter)

private ObjectQuery<Customer> IncludeOrders(this ObjectQuery<Customer> qry)

しかし、それは複雑すぎるように見えるので、これは私を納得させません。

ありがとう、マルコ

4

2 に答える 2

1

プレゼンテーション層とビジネス層の間のインターフェイスについては、DTOに移行することを検討してください。例を参照してください。-http://msdn.microsoft.com/en-us/magazine/ee236638.aspx

Automapperのようなものは、DTOへの移動に関連する苦痛の多くを軽減でき、移動により、クエリの結果で実行できることと実行できないことが明示されます。つまり、DTOにある場合は、ロードされ、別のDTOが必要でない場合は、 。

現在の計画は、プレゼンテーション層とデータ層の間でかなり緊密に結合されているように聞こえます。

于 2010-04-10T00:00:13.727 に答える
1

DTOの使用に関するHightechriderからのコメントに同意しますが、事業体に関しては有効な質問があります。

考えられる解決策の1つ(開発中のプロジェクトでこれらの線に沿って何かを使用しています)は、読み取り専用のDTOを使用することです(少なくともプレゼンテーション層の観点からは。クエリ/取得操作はDTOのみを返します。これは遅延読み込み機能を提供します。

オブジェクト/エンティティが更新/作成されたときにDTOをラップする編集可能なオブジェクトを返すようにビジネスレイヤーを設定できます。編集可能なオブジェクトは、任意のビジネスルールを適用でき、それが保存/ビジネスレイヤーに渡されると、ラップされたDTO(更新された値を含む)がデータレイヤーに渡されます。

public class Editable
{
    //.......initialize this, other properties/methods....

    public bool CanEdit<TRet>(Expression<Func<Dto, TRet>> property)
    {
        //do something to determine can edit
        return true;
    }

    public bool Update<TRet>(Expression<Func<Dto, TRet>> property, TRet updatedValue)
    {
        if (CanEdit(property))
        {
            //set the value on the property of the DTO (somehow)
            return true;
        }
        return false;
    }

    public Dto ValueOf { get; private set;}
}

これにより、ユーザーが編集可能なオブジェクトをビジネスレイヤーから取得できるかどうかを強制できるほか、ユーザーがオブジェクトの特定のプロパティを編集する権限を持っている場合にビジネスオブジェクトを強制できるようになります。私が働いているドメインで遭遇する一般的な問題は、一部のユーザーはすべてのプロパティを編集でき、他のユーザーは編集できないのに対し、誰もがプロパティの値を表示できることです。さらに、プレゼンテーション層は、ビジネス層によって指示および実施されるように、ユーザーに編集可能として公開するものを決定する機能を取得します。

私が持っていた他の考えは、ビジネスレイヤーがIQueryableを公開したり、データレイヤーに渡す引数として標準式を使用したりすることはできないということです。たとえば、次のようなページ構築クエリがあります。

public class PageData
{
    public int PageNum;
    public int TotalNumberPages;
    public IEnumerable<Dto> DataSet;
}

public class BL
{
    public PageData GetPagedData(int pageNum, int itemsPerPage, Expression<Func<Dto, bool>> whereClause)
    {
        var dataCt = dataContext.Dtos.Where(whereClause).Count();
        var dataSet = dataContext.Dtos.Where(whereClause).Skip(pageNum * itemsPerPage).Take(itemsPerPage);

        var ret = new PageData
                        { 
                          //init this
                        };

        return ret;
    }
}
于 2010-04-10T00:54:38.347 に答える