Inner query inside Wcf Services query throws '

2019-07-28 09:54发布

I have a class with a many-many relationship and I'm having problems in properly filtering the results from a query made using Wcf Data Services (through the DataServiceQuery class). This service exposes an Entity Framework 5 model.

This simple query for instance:

from device in devices
select new 
{
    DeviceName = device.Name,
    TestUsers = device
        .Allocations
        .Where(allocation => allocation.User == "testUser")
}

This gives me a NotSupportedException, at runtime:

[NotSupportedException: Constructing or initializing instances of the type <>f__AnonymousType0`4[System.String,System.String,System.String,System.Collections.Generic.IEnumerable`1[Mobiltec.M3S.Model.AllocInfo]] with the expression device.Allocations.Where(_allocation => (_allocation.User == "testUser")) is not supported.]
   System.Data.Services.Client.NonEntityProjectionAnalyzer.VisitMethodCall(MethodCallExpression m) +650
   System.Data.Services.Client.ALinqExpressionVisitor.Visit(Expression exp) +456
   System.Data.Services.Client.ALinqExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original) +107
   System.Data.Services.Client.ALinqExpressionVisitor.VisitNew(NewExpression nex) +52
   System.Data.Services.Client.NonEntityProjectionAnalyzer.VisitNew(NewExpression nex) +226
   System.Data.Services.Client.ALinqExpressionVisitor.Visit(Expression exp) +552
   System.Data.Services.Client.NonEntityProjectionAnalyzer.Analyze(Expression e, PathBox pb, DataServiceContext context) +285
   System.Data.Services.Client.ProjectionAnalyzer.Analyze(LambdaExpression e, PathBox pb, DataServiceContext context) +226
   System.Data.Services.Client.ProjectionAnalyzer.AnalyzeResourceExpression(LambdaExpression lambda, ResourceExpression resource, DataServiceContext context) +58
   System.Data.Services.Client.ProjectionAnalyzer.Analyze(LambdaExpression le, ResourceExpression re, Boolean matchMembers, DataServiceContext context) +335
   System.Data.Services.Client.ResourceBinder.AnalyzeProjection(MethodCallExpression mce, SequenceMethod sequenceMethod, Expression& e) +1000
   System.Data.Services.Client.ResourceBinder.VisitMethodCall(MethodCallExpression mce) +149
   System.Data.Services.Client.ALinqExpressionVisitor.Visit(Expression exp) +456
   System.Data.Services.Client.ALinqExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original) +107
   System.Data.Services.Client.ALinqExpressionVisitor.VisitMethodCall(MethodCallExpression m) +87
   System.Data.Services.Client.ResourceBinder.VisitMethodCall(MethodCallExpression mce) +177
   System.Data.Services.Client.ALinqExpressionVisitor.Visit(Expression exp) +456
   System.Data.Services.Client.ResourceBinder.Bind(Expression e, DataServiceContext context) +57
   System.Data.Services.Client.DataServiceQueryProvider.Translate(Expression e) +252
   System.Data.Services.Client.DataServiceQuery`1.Translate() +37
   System.Data.Services.Client.DataServiceRequest.GetQuerySetCount(DataServiceContext context) +77
   System.Data.Services.Client.DataServiceQueryProvider.ReturnSingleton(Expression expression) +332

If I only project data in there, instead of filtering, like this:

from device in devices
select new 
{
    DeviceName = device.Name,
    AllocatedUsers = device
        .Allocations
        .Select(allocation => allocation.User)
}

It works as expected.

3条回答
趁早两清
2楼-- · 2019-07-28 09:56

actually you are doing assignment in your where statement

from device in devices
select new 
{
    DeviceName = device.Name,
    TestUser = device
        .Allocations
        .Where(allocation => allocation.User = "testUser") // use == for equality
}
查看更多
可以哭但决不认输i
3楼-- · 2019-07-28 09:58

try to test for equality instead of assigning

.Where(allocation => allocation.User == "testUser")

notice the double ==

查看更多
仙女界的扛把子
4楼-- · 2019-07-28 09:59

OData's $select clause (which is what the Linq select maps to in the URL) does not support projections that transform property values, at least in OData v3. Projections are used more to reduce the number of properties that you need to work with, rather than to manipulate the property values.

So this is fine and supported:

from device in devices
select new 
{
    DeviceName = device.Name,
    TestUsers = device.Allocations
}

but as soon as you put the .Where clause on Allocations, there is no way to transform that into OData URL syntax.

查看更多
登录 后发表回答