2016-09-22 23 views
0

私は、Web API、Entity FrameworkのとのODataに新しいです。私は別のフォーラムで同様の質問をしましたが、関連する回答は得られていません。のWeb APIのODataカスタムクエリ問題

我々は、Salesforceで使用するためのOData準拠のWeb APIサービスを持っています。オラクルには、複雑なクエリを公開して公開する必要があります。

私たちはODATAパラメータフィルタリングが発生するためにも許可するようにカスタムクエリを使用する方法がわからないのですか? ($ filter、$ top、$ skipなど)たとえば、$フィルタを使用すると、そのフィルタをカスタムクエリに適用し、それをデータベースに戻して結果セットを返すようにしたいとします。これどうやってするの?

私が持っているように見える問題は、彼らが来るが、彼らは、Oracleに渡されるクエリに翻訳されていないとして、私はパラメータを見ることができるということです。それは、完全な結果セットを返すクエリを起動し、次にパラメータを適用するようです。結果セットが非常に大きいため、これは非常に遅いです。

私は2つのものを見つけようとしています 1.カスタムSQLを使用して、元のクエリにodataパラメータを適用するにはどうすればよいですか? 2. EFまたはカスタムクエリを使用する場合、どのようにクエリにodataパラメータを適用して、クエリがデータベースに送信されたときに$ filterパラメータがクエリに含まれるようにすることができますか?私は完全な結果が返され、フィルタを適用したくない。

誰でも私にこれを実現させる方法についてのいくつかの指針を与えることができますか?

private static ODataValidationSettings _validationSettings = new ODataValidationSettings(); 

    //public IHttpActionResult GetName() 
    //{ } 

    // GET: odata/ShareData 
    [ODataRoute("Orders")] 
    [EnableQuery(PageSize = 50)] 
    public IHttpActionResult GetOrders(ODataQueryOptions<Orders> queryOptions) 
    { 
     // validate the query. 
     try 
     { 
      queryOptions.Validate(_validationSettings); 
     } 
     catch (ODataException ex) 
     { 
      return BadRequest(ex.Message); 
     } 

     try 
     { 
      string connectionString = ConfigurationManager.ConnectionStrings["DNATestConnectionString"].ConnectionString; 
      var items = GetDataItems(connectionString); 
      return Ok<IEnumerable<Orders>>(items); 
     } 
     catch (Exception ex) 
     { 
      return StatusCode(HttpStatusCode.InternalServerError); 
     } 
    } 



    #region Load Data Methods 
    private static List<Orders> GetDataItems(string connectionString) 
    { 
     List<Orders> items = new List<Orders>(); 

     using (OracleConnection con = new OracleConnection(connectionString)) 
     { 
      con.Open(); 

      using (OracleCommand cmd = con.CreateCommand()) 
      { 
       cmd.CommandText = "select po_header_id, segment1, vendor_id, vendor_site_id from po_headers_all where vendor_id=4993"; 
       using (OracleDataReader rdr = cmd.ExecuteReader()) 
       { 
        while (rdr.Read()) 
         items.Add(ToOrders(rdr)); 
       } 
      } 
     } 

     return items; 
    } 

    private static Orders ToOrders(OracleDataReader rdr) 
    { 
     Orders data = new Orders(); 

     data.VENDOR_ID = ToInt32(rdr, "VENDOR_ID"); 
     data.VENDOR_SITE_ID = ToInt32(rdr, "VENDOR_SITE_ID"); 
     data.PO_HEADER_ID = ToInt32(rdr, "PO_HEADER_ID"); 
     data.SEGMENT1 = Convert.ToString(rdr["SEGMENT1"]); 

     return data; 
    } 

    private static int ToInt32(OracleDataReader rdr, string name) 
    { 
     int index = rdr.GetOrdinal(name); 
     return rdr.IsDBNull(index) ? 0 : Convert.ToInt32(rdr[index]); 
    } 
    #endregion 

答えて

0

私はこれが可能ではないと思います。

  1. どのように私は、カスタムSQLを使用し、基本的なクエリにODATAパラメータを適用することができますか?

私の知る限り、あなたはできません。 ODataライブラリ全体のポイントは、IQueryableを処理する必要があることです。あなたの例のように文字列にカスタムSQLを使用すると、渡されているODataパラメータと組み合わせることはできません。

SQLビューでカスタムSQLを作成してから、テーブルを追加するのと同じ方法で、EFモデルへのSQLビュー - テーブルと同じようにDbSetとして表されます。次のように

その後、データセットを表し、その後、ODataのパラメータを適用するためのIQueryableを取得することができます。

public IHttpActionResult GetOrders(ODataQueryOptions<OrdersView> queryOptions) 
{ 
    IQueryable<OrdersView> allData = // ... get the DbSet from entity framework... 

    // this will apply the OData query to the data set and only pull the data you want from the database 
    var filteredResults = queryOptions.ApplyTo(allData) as IQueryable<OrdersView>; 


    return Ok<IQueryable<OrdersView>>(filteredResults); 
} 
関連する問題