1

ReflectionDataProviderでWCFDataServices5.3.0を使用しています。ソースデータはRavenDBに保存されているため、すべてのクエリが延期されます。それで、ODataフィルターが適用された後、結果がクライアントに返される前に、クエリに対して.ToList()を呼び出す方法はありますか?

更新:私のDataModelプロパティ宣言

    public IQueryable<PositionModel> Positions
    {
        get
        {
            using (var session = OLAPDocumentStore.OpenSession())
            {
                return session
                    .Query<ConsolidatedApplicationPosition>()
                    .Select(x => new PositionModel
                                     {
                                         ApplicationId = x.ApplicationId,
                                         CategoryId = x.CategoryId,
                                         ID = x.Id,
                                         Platform = x.Platform,
                                         Position = x.Position,
                                         RegionalCode = x.RegionalCode,
                                         Timestamp = x.Timestamp,
                                         TopListId = x.TopListId
                                     })
                    .AsQueryable();
            }
        }
    }

解決策@matt-johnsonの回答を参照し、モデルのすべてのプロパティに[DataMember]を追加することを忘れないでください

[DataContract, DataServiceKey("Id")]
public class PositionModel
{
    [DataMember]
    public string Id { get; set; }
    [DataMember]
    public string ApplicationId { get; set; }
    [DataMember]
    public string CategoryId { get; set; }
    [DataMember]
    public int Position { get; set; }
    [DataMember]
    public string RegionalCode { get; set; }
    [DataMember]
    public DateTime Timestamp { get; set; }
    [DataMember]
    public string TopListId { get; set; }
}
4

1 に答える 1

2

さて、WCF Data Services がどのように機能するかについて、記憶を新たにする必要がありました。Shawn Wildermuthの素晴らしいサンプル ビデオがあります。

Select主な問題は、ステートメントを使用してクライアント側のクエリを変換しようとしていることです。を返すとIQueryable、それは linq プロバイダーに直接フックすることになっています。この場合、RavenDB クエリの出力です。適用Whereおよびフィルター処理はできますが、ステートメントOrderByでプロジェクションを実行することはできません。Selectこれにより、クエリチェーンが壊れます。

したがってConsolidatedApplicationPosition、データベースにあるPositionModelオブジェクトから、WCF Data Services に返すオブジェクトに射影する場合は、別の方法で行う必要があります。以下にいくつかのオプションを示します。

  1. 射影する必要があるすべてのフィールドが既にソース データにある場合は、次の操作を実行できます。

    return session.Query<ConsolidatedApplicationPosition>()
                  .AsProjection<PositionModel>();
    

    ここでの唯一の問題は、識別子が一致しないことです。Raven のデフォルトの識別子規則はId(Pascal ケース) ですが、WCF はID(大文字) です。Raven の規則を変更することで、それらを並べることができます。

    DocumentStore.Conventions.FindIdentityProperty = x => x.Name == "ID";
    

    DataServiceKeyまたは、次の属性を使用して WCF の規則を変更します。

    [DataContract, DataServiceKey("Id")]
    public class PositionModel
    {
        [DataMember]
        public int Id { get; set; }
    
        ...
    }
    
  2. 識別子の不一致を維持したい場合、またはより多くのフィールドを変換したい場合は、動的インデックスを使用できません。代わりに、静的インデックスを作成し、変換を使用して射影を制御する必要があります。

    public class YourIndex : AbstractIndexCreationTask<ConsolidatedApplicationPosition>
    {
      public YourIndex()
      {
        Map = docs =>
          from doc in docs
          select new
          {
            // You need to map any fields that you might query
            // or sort on through the odata filters.
          };
    
        TransformResults = (database, docs) =>
          from doc in docs
          select new PositionModel
          {
            // if you need integer identifiers in your result,
            // you'll have to split them from the doc key, like this:
            ID = int.Parse(doc.Id.ToString().Split('/')[1]),
    
            // otherwise, just do this:
            ID = doc.Id,
    
            // bring over all of your other fields as well
            Platform = doc.Platform
            ... etc ...
    
         };
      }
    }
    

    インデックスを配置したら、次のようにクエリします。

    return session.Query<PositionModel, YourIndex>();
    

どちらのオプションでも、クエリに select ステートメントがないため、ToListorを実行する必要はありませんAsQueryableIQueryableRavenDB linq プロバイダーのインターフェイスを WCF Data Service コンテキストに送信するだけです。

于 2013-03-04T15:37:42.800 に答える