1

これと同じ問題が発生し続けます。永続的なバッキングを持たないビューモデルがあります。検索入力フォームを生成するのは単なる ViewModel です。

ユーザーが入力した値から大きな where 句を作成したいと考えています。アクションがパラメーター SearchViewModel として受け入れる場合、viewModel をサービス層に渡さずにこれを行うにはどうすればよいですか? サービスは ViewModels について知っているべきではありませんか? ああ、シリアル化すると、大きな文字列になり、キー/値が厳密に型指定されます。

SearchViewModelこれは単なるスニペットです。

[Display(Name="Address")]
  public string AddressKeywords { get; set; }

        /// <summary>
        ///     Gets or sets the census.
        /// </summary>
        public string Census { get; set; }

        /// <summary>
        ///     Gets or sets the lot block sub.
        /// </summary>
        public string LotBlockSub { get; set; }

        /// <summary>
        ///     Gets or sets the owner keywords.
        /// </summary>
        [Display(Name="Owner")]
        public string OwnerKeywords { get; set; }

私のコントローラーアクションでは、このようなことを考えていました。しかし、このロジックはすべてコントローラーに属していないと思います。

ActionResult GetSearchResults(SearchViewModel model){
    var query = service.GetAllParcels();
    if(model.Census != null){
    query = query.Where(x=>x.Census == model.Census);
    }
    if (model.OwnerKeywords != null){
    query = query.Where(x=>x.Owners == model.OwnerKeywords);
    }
    return View(query.ToList());
    }
4

3 に答える 3

2

ここで行っているのは、より厳密な OO "仕様パターン" の代わりに LINQ を使用することです。アプリケーションの階層化が許可されている場合 (つまり、Web フロント エンドからデータベースに直接アクセスできる場合。すべてのアーキテクチャがそうではありません)、実行するのではなく「サービス」クラスにプッシュしたい場合がありますが、それは問題ありません。コントローラー内の多くのクエリ ロジック。これらの種類のものをどの程度厳密に分離したいかは、アプリケーションのサイズと複雑さによって異なります。

少し抽象化を導入する 1 つの方法は、クエリ述語で使用できるプロパティを定義するインターフェイス (ISearchSpecification など) をビュー モデルに実装させることです。次に、インターフェイスで動作するクラスまたは拡張メソッドを作成できます。

public interface IMySearchSpec 
{
   string City { get; }
   string State { get; }
}

public class MyViewModel : IMySearchSpec
{
   ...implement IMySearchSpec and perhaps other things...
}

public static class QueryExtensions
{
   public static IQueryable<T> ApplyPredicate(this IQueryable<T> query, IMySearchSpec searchSpec) 
   {
        if (searchSpec.City != null )
        {
            query = query.Where( x => x.City == searchSpec.city );
        }
        // ..etc..
       return query;
   }
}

// then, in your controller
var filteredQuery = query.ApplyPredicate(viewModel);

同様の方法でページング/ソート ロジックを適用することもできます。

于 2013-06-25T19:05:02.927 に答える
2

ビューモデルをサービス層に渡さずにこれを行うにはどうすればよいですか? サービスは ViewModels について知っているべきではありませんか?

そうです、ビューモデルはプレゼンテーション レイヤー オブジェクトなので、サービス レイヤーまたは永続レイヤーから除外することをお勧めします。また、コントローラーは無駄がなく、多くのロジックを持たない必要があるため、このコードを別の場所に因数分解するのが正しいアプローチだと思います。状況に応じたいくつかの代替手段を次に示します。

  • コントローラーからサービス層に値を渡す
  • 文字列を作成するヘルパー クラスを作成する
  • ビューモデルを別のクラス/エンティティにマップし、これをサービスレイヤーに渡します
于 2013-06-25T19:09:13.267 に答える
1

通常、代わりにビューからビューモデルをパラメータとして取得しません。ビューモデルはコントローラーからビューに渡されます。

私のロジックの背後にある理由は、大規模な (大量のデータ) ビューモデルがコントローラーからビューに渡され、ビューからコントローラーに渡されると問題 (パフォーマンス) になる可能性があるということです。特に、コントローラ アクションのすべての情報が必要ない場合。ビューによって作成されたビューモデルをコントローラー (元のより大きなビューモデルのサブセット) に送信できると思います。質問に対する私の理解は、彼が同じビューモデルをコントローラー -> ビュー -> コントローラーの間で行き来させたいということでした。

stackoverflow の質問からMVC では、ViewModel とは何ですか? :

ViewModel は、Model が保持するデータ型から、View が便利に操作できるデータ型への変換も実行できます。これは、ViewModel がモデルを直接運ぶのではなく、同じ情報 (おそらくそのサブセット) をより適切な形式で運ぶ他の容器を意味することさえあります。

アルバムと DVD を集約する Library モデルがあるとします。そのようなモデルと対応する ViewModel の違いは、ViewModel が次の明確な目的を持っているのに対し、Model は View を気にしない (または認識さえしない) ということです。それを促進します。

コントローラー アクションのパラメーターを、SearchParameters などのクラスに変更します。SearchParameters をサービス層に渡しても問題ありません。

于 2013-06-25T18:56:53.583 に答える