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.
actually you are doing assignment in your where statement
try to test for equality instead of assigning
notice the double ==
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:
but as soon as you put the
.Where
clause onAllocations
, there is no way to transform that into OData URL syntax.