1

(5.6) を使用Microsoft.Data.Odataして次のクエリを実行しています。

IEnumerable<Service> services = context.Services.Expand(ServiceQueryExpansion)
    .Where(c =>
        (serviceNames.Any(s => s.Equals(
            c.ServiceName, StringComparison.OrdinalIgnoreCase))))

serviceNames は文字列の IEnumerable です

上記のクエリを実行すると、次のエラーが発生します。

Error translating Linq expression to URI: The source parameter for the 'Any' method has to be either a navigation or a collection property.

これを解決するにはどうすればよいですか?

4

3 に答える 3

3

面白くてわくわくする (皮肉) ことは知っていますが、次のように Where 式を動的に作成できます。

var serviceNames = new string[] { "SERVICE1","SERVICE2"};

Expression<Func<Service,bool>> inList = v => false;
var parameter = inList.Parameters[0];
var propertyExpression = Expression.Property(parameter,"ServiceName");

foreach (var serviceName in serviceNames)
{
   var body = inList.Body;
   var constantExpression = Expression.Constant(serviceName);
   var equalityExpression = Expression.Equal(propertyExpression,constantExpression);

   body = Expression.OrElse(body,equalityExpression);

   inList = Expression.Lambda<Func<Service, bool>>(body, parameter);
}

IEnumerable<Service> services = context.Services.Expand(ServiceQueryExpansion)
    .Where(inList);

このメソッドは、リストから (v => v.ServiceName == "Service1" || v.ServiceName == "Service2" || v.ServiceName == "Service3") に似たカスタム where 句を作成します。

私のブログhttps://secureapplicationlifestyle.com/2013/07/filter-pattern-for-linq-query-filter.htmlの指示に従って、このロジックをカスタムの "WhereContains(yourListHere)" カスタム フィルター拡張機能にカプセル化することができます。方法。

于 2013-08-29T14:29:31.717 に答える
0

あなたは書くことができます:

var services = context.Services.Expand(ServiceQueryExpansion).AsEnumerable()
      .Where(c => serviceNames.Contains(c.ServiceName));

ただし、サービス コレクション全体がダウンロードされます。または:

var services = serviceNames.SelectMany(s=>
     context.Services.Expand(ServiceQueryExpansion).Where(c=> c.ServicaName == s));

これにより、N 個のリクエストが作成されます。

Linq to OData でこれを行うより良い方法がわかりません。

于 2013-08-29T12:47:38.170 に答える
0

私がしたことは、可能なフィルターを適用してから、結果をローカルに取得したら、リストしてから別のフィルターを作成することでした。

var services = context.Services.Expand(ServiceQueryExpansion).ToList();
services = services.Where(s => serviceNames.Any(n => n.ServiceName.Equals(s, StringComparison.OrdinalIgnoreCase)));

ネットワーク経由で取得する必要のないレコードが複数ある場合、これは最適なオプションではありません。

もう 1 つのオプションは、データ サービス オペレーションを作成することです。

[WebGet]
public IQueryable<Service> GetServicesByServiceName(string serviceNames)
{
    var serviceNamesArray = serviceNames.Split(',');
    var ctx = YourContext();
    return ctx.Services.Include("ServiceQueryExpansion").Where(s => serviceNamesArrays.Any(n => s.ServiceName.Equals(n, StringComparison.OrdinalIgnoreCase))).AsQueryable();
}
于 2014-09-29T03:01:59.120 に答える