Web API OData自定义查询问题
问题描述:
我是Web API,实体框架和OData的新手。我在另一个论坛上提了一个类似的问题,但没有得到相关的答复。Web API OData自定义查询问题
我们在Salesforce中使用了适用于OData的Web API服务。我们需要公开一个Oracle自定义复杂查询。
我不知道如何使用自定义查询,就像我们也想允许odata参数过滤发生? ($ filter,$ top,$ skip等)例如,当使用$ filter时,我想将该过滤器应用于自定义查询,然后将其发送回数据库以使其返回结果集。我怎样才能做到这一点?
我似乎有的问题是,我可以看到参数,因为他们进来,但他们没有转化为查询被传递给甲骨文。它似乎会触发查询返回完整的结果集,然后应用参数。这是非常缓慢的,因为结果集非常大。
我希望2弄清楚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
答
我不认为这是可能的。
- 如何使用自定义的SQL和应用的OData参数为基础的查询?
据我所知,你不能。 OData库的重点在于它需要处理一个IQueryable
。通过在您的示例中使用字符串中的自定义SQL,您无法将其与正在传入的OData参数结合使用。
一种方法是将自定义SQL放在SQL视图中,然后添加以与添加表相同的方式将EF视图添加到EF模型 - 它将像表一样被表示为DbSet。
然后,您可以得到一个IQueryable来表示数据集,然后应用的OData参数如下:
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);
}