1

モバイルアプリケーションとASP.NETMVC4Webアプリで使用するWebAPIを作成しています。私たちは巨大なデータベースを扱っているので、可能な限りエンティティのリストを具体化することを避ける必要があります。WebAPIはJSONを返します。

状況は単純です...ライセンスのリストの要求を受け取りますが、返される可能性のあるレコードが500,000あるため、ページングする必要があります。返されるビューモデルのリストに変換する前に、エンティティのIQueryableリストにページング/フィルタリングを適用するにはどうすればよいですか?

これが私が使っているいくつかのテストコードです...

    // Get the list of licenses, but page them.
    // GET api/<controller>
    //[Queryable] 
    public IQueryable<LicenseViewModel> Get()
    {
        Mapper.CreateMap<LicenseEntity, LicenseViewModel>();
        Mapper.AssertConfigurationIsValid();

        List<LicenseViewModel> vms = new List<LicenseViewModel>();
        using (var repo = new LicenseRepository())
        {
            // Get the IQueryable<LicenseEntity> list...
            // IS THERE SOME WAY TO APPY PAGING/FILTERING HERE?
            var entities = repo.List();

            // Convert them to viewmodels.  ARGGG! This will materialize the huge list
            // if we cannot applyfiltering/paging in the previous step.
            foreach (var item in entities)
            {
                var vm = Mapper.Map<LicenseEntity, LicenseViewModel>(item);
                list.Add(vm);
            }
        }

        return vms.AsQueryable();
    }

次のことを試しましたが、リストを展開して結果を確認しようとすると、「子供を評価できませんでした」というエラーが表示されます。

            using (var repo = new LicenseRepository())
            {
                // Get the list of entities...
                var list = repo
                    .List()
                    .Select(x => Mapper.Map(x, new LicenseViewModel()));

                return list;
            }

あなたの時間とあなたの提案をありがとう、

マイク

4

4 に答える 4

0

//LicenseEntityオブジェクトのIQueryableリストを取得します。var entityList = LicenseRepository.List(adapter);

//リストを//LicenseViewModelオブジェクトのIQueryableリストに変換します。var vmList = entityList.Select(x => AutoMapper.Mapper.Map(x、new LicenseViewModel()));

于 2012-11-30T16:55:47.210 に答える
0

ページングには、最近追加された ResultLimit 機能を使用できます。あなたは言うことができます、

[Queryable(ResultLimit=10)] 

一度に 10 個のアイテムのみを返します。

そして、これの最もクールな部分は、次のページのリンクも計算することです。次のページのリンクは、クライアントが次のページを取得するためにたどる必要があるリンクです。ODataFormatter を使用している場合、次のページへのリンクがデフォルトで応答に含まれます。別のフォーマッタを使用している場合は、リンクを計算するだけですが、その形式がわからないため、応答本文には入れません。リンクを取得するためのメッセージ ハンドラーまたはアクション フィルターを作成できます。

Request.Properties['MS_NextPageLink'] 

応答本文または応答ヘッダー、またはクライアントが期待する場所に書き込みます。

于 2012-11-30T03:14:15.047 に答える
0

ドメインエンティティをビューモデルに投影するためのソリューションを見つけました。私と同じ種類の問題に苦しんでいる場合は、次のリンクを確認してください。

http://lostechies.com/jimmybogard/2011/02/09/autoprojecting-linq-queries/ http://www.devtrends.co.uk/blog/stop-using-automapper-in-your-data-access-コード

ところで、私のドメイン エンティティの 1 つに、いくつかの「計算された」プロパティを持つ部分クラスがありました...値がデータベース レコードの他のフィールドから生成されたプロパティ。これらは、前述のソリューションに干渉するため、ドメイン エンティティに含めることはできません。それらを実際に必要な ViewModel クラスに移動しましたが、すべて問題ありません。

この情報がお役に立てば幸いです...

マイク

于 2012-12-01T07:17:04.880 に答える
0

これが Web API にどのようにマップされるかはわかりませんが、プリンシパルは同じです。

基本的に同じであるWCF Dataservicesを使用すると、現在、ページサイズを次のように設定できるいくつかの追加機能があると思います。

 public static void InitializeService(DataServiceConfiguration config)
 {
        config.SetEntitySetPageSize("*", 20);
 }

"*" には、エンティティ セット名を挿入します。

これを設定すると、クライアントが次のページをリクエストするために使用できる継続トークンがフィードに含まれます。

リポジトリでは、データ ソースによっては、Take および Skip 関数を手動で処理する必要がある場合があります。

URL に ?$top=10&$skip=0 が含まれている場合、これをデータソースからのリクエストに追加できます。以下の例を参照してください。

using (var repo = new LicenseRepository())
{
     // Get the list of entities...
     var list = repo                        
     .Select(x => Mapper.Map(x, new LicenseViewModel()))
     .Skip(0)
     .Take(10);
     return list;
}

URL の $top 要素と $skip 要素の内容に応じて、skip/take の値を明らかに変更します。

于 2012-11-29T22:24:43.043 に答える