从OData端点检索行的子集

时间:2017-02-14 16:14:10

标签: c# asp.net-mvc linq asp.net-web-api odata

我发布了一个公开OData端点的ASP.NET Web API。

在前端我使用ASP.NET MVC 5.使用 WCF服务引用来使用端点。

我面临的问题是,我需要在给定ID列表的情况下从端点检索行的子集。

这是我在OData端点

中使用的实体
class MyEntity
{
  public int ID {get; set;}
  public string Name {get; set;}
  public int Age {get; set;}
}

使用 LINQ 我在其他情况下使用以下语句解决了这个问题

var result = entitiesContext.MyEntity
  .Where(x => idsEmployees.Select(y => y).Contains(x.ID));

其中 idsEmployees 是我需要检索的员工的ID列表。

在当前场景中使用此语句,我得到以下异常:

  

将Linq表达式转换为URI时出错:方法'包含'不是   支撑。

我该如何解决这个问题?

谢谢。

1 个答案:

答案 0 :(得分:1)

经过一番挖掘后,我在这个博客中找到了一个解决方案

https://blogs.msdn.microsoft.com/phaniraj/2008/07/16/set-based-operations-in-ado-net-data-services/

这是解决问题的扩展方法

/// <summary>
/// Retrieves the subset of entities in a table exposed through OData
/// </summary>
/// <typeparam name="T">Entity type</typeparam>
/// <typeparam name="U">Subset type</typeparam>
/// <param name="query"></param>
/// <param name="Set"></param>
/// <param name="propertyExpression"></param>
/// <returns></returns>
public static DataServiceQuery<T> SubSet<T, U>(
    this DataServiceQuery<T> query, 
    IEnumerable<U> Set, 
    Expression<Func<T, U>> propertyExpression)
{
    //The Filter Predicate that contains the Filter criteria
    Expression filterPredicate = null;
    //The parameter expression containing the Entity Type
    var param = propertyExpression.Parameters.Single();
    //Get Key Property 
    //The Left Hand Side of the Filter Expression
    var left = propertyExpression.Body;
    //Build a Dynamic Linq Query for finding an entity whose ID is in the list
    foreach (var id in Set)
    {
        //Build a comparision expression which equats the Id of the Entity with this value in the IDs list
        // ex : e.Id == 1
        Expression comparison = Expression.Equal(left, Expression.Constant(id));
        //Add this to the complete Filter Expression
        // e.Id == 1 or e.Id == 3
        filterPredicate = (filterPredicate == null) 
            ? comparison 
            : Expression.Or(filterPredicate, comparison);
    }

    //Convert the Filter Expression into a Lambda expression of type Func<Lists,bool>
    // which means that this lambda expression takes an instance of type EntityType and returns a Bool
    var filterLambdaExpression = 
        Expression.Lambda<Func<T, bool>>(filterPredicate, param);
    return (DataServiceQuery<T>)query.Where<T>(filterLambdaExpression);
}

这是使用它的方式

var result = entitiesContext.MyEntity.Subset<MyEntity, int>(idsEmployees, x => x.ID);