9

WebApi で OData を実装しようとしています。私はリポジトリ パターンと EF5 (バックエンド) を使用していますが、これは私が見つけたすべての例と一致しています。ここで物事が不安定になります。コントローラーで AutoMapper を使用してマップされているモデルの背後にある EF 生成クラスを非表示にしようとしています。私が見た例は、レポから出てくるものは何でも返すようです

OData パラメーターを (マップされた結果に) コントローラーに適用するのではなく、実行の遅延から値を保持するためにリポジトリに適用したいと考えています。ODataCriteria をリポジトリに渡すことはできますが、適用しようとすると、オプション/結果が IQueryable< EF_Class > ではなくプレゼンテーション層から IQueryable< Model > に入力されているように見えるため、エラーが発生します。

別の投稿で他の誰かがこれを回避しているのを見ましたが、それは投稿の小さな部分であり、役に立たなかったようです.

他の誰かがこれに対処しましたか?EF クラスを公開したくありません。ああ、私は最初にDBを使用しています。

前もって感謝します...

4

2 に答える 2

0

要件を示すコードを次に示します。

結果を得るには、( を使用して) クエリが実行されていることを確認する必要がありますToList()。これを行う最も効率的な方法は、ページング (ボーナス) を追加してPageResult<>オブジェクトを返すことです。

public PageResult<WebPoco> Get(ODataQueryOptions<WebPoco> queryOptions)
{
    var data2 = DatabaseData();

    //Create a set of ODataQueryOptions for the internal class
    ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
    modelBuilder.EntitySet<DatabasePoco>("DatabasePoco"); 
    var context = new ODataQueryContext(
         modelBuilder.GetEdmModel(), typeof(DatabasePoco));
    var newOptions = new ODataQueryOptions<DatabasePoco>(context, Request);

    var t = new ODataValidationSettings() { MaxTop = 25 };
    var s = new ODataQuerySettings() { PageSize = 25 };
    newOptions.Validate(t);
    IEnumerable<DatabasePoco> results =
        (IEnumerable<DatabasePoco>)newOptions.ApplyTo(data2, s);

    int skip = newOptions.Skip == null ? 0 : newOptions.Skip.Value;
    int take = newOptions.Top == null ? 25 : newOptions.Top.Value;

    List<DatabasePoco> internalResults = results.Skip(skip).Take(take).ToList();

    // map from DatabasePoco to WebPoco here:
    List<WebPoco> webResults; 

    PageResult<WebPoco> page =
        new PageResult<WebPoco>(
            webResults, Request.GetNextPageLink(), Request.GetInlineCount());

    return page;
}

ここに using ステートメントがあります

using System.Web.Http;
using System.Web.Http.OData;
using System.Web.Http.OData.Builder;
using System.Web.Http.OData.Query;

テストクラス

public class WebPoco
{
    public int id { get; set; }
    public string name { get; set; }
    public string type { get; set; }
}

public class DatabasePoco
{
    public int id { get; set; }
    public string name { get; set; }
    public string type { get; set; }
}

およびテスト用のいくつかのデータ

private IQueryable<DatabasePoco> DatabaseData()
{
    return (
        new DatabasePoco[] { 
            new DatabasePoco() { id = 1, name = "one", type = "a" },
            new DatabasePoco() { id = 2, name = "two", type = "b" },
            new DatabasePoco() { id = 3, name = "three", type = "c" },
            new DatabasePoco() { id = 4, name = "four", type = "d" },
            new DatabasePoco() { id = 5, name = "five", type = "e" },
            new DatabasePoco() { id = 6, name = "six", type = "f" },
            new DatabasePoco() { id = 7, name = "seven", type = "g" },
            new DatabasePoco() { id = 8, name = "eight", type = "h" },
            new DatabasePoco() { id = 9, name = "nine", type = "i" }
        })
        .AsQueryable();
}
于 2013-05-17T10:32:28.607 に答える
0

返す Queryable が、AutoMapper ではなく dbContext.dbSet.Select(x => new Model { Id = x.Id}) メカニズムを介している場合。次に、Queryable に条件を適用すると、EF LINQ プロバイダーによって自動的に変換および評価されます。それ以外の場合は、Model プロパティに基づく式から EF_Class プロパティに基づく式に式を変更するカスタム LINQ プロバイダーを作成する必要があります。

于 2013-05-16T22:01:03.570 に答える