Wcf Services查询中的内部查询抛出'NotSupportedException'

时间:2013-11-12 20:17:37

标签: c# linq entity-framework-5 odata wcf-data-services

我有一个有很多关系的类,我在使用Wcf数据服务(通过DataServiceQuery类)进行的查询中正确过滤结果时遇到了问题。此服务公开了Entity Framework 5模型。

这个简单的查询例如:

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

这在运行时给了我NotSupportedException

[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

如果我只在那里投影数据,而不是像这样过滤:

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

它按预期工作。

3 个答案:

答案 0 :(得分:1)

尝试测试相等而不是分配

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

注意double ==

答案 1 :(得分:1)

实际上你在where where语句中做作业

from device in devices
select new 
{
    DeviceName = device.Name,
    TestUser = device
        .Allocations
        .Where(allocation => allocation.User = "testUser") // use == for equality
}

答案 2 :(得分:1)

OData的$ select子句(这是Linq select在URL中映射的内容)不支持转换属性值的投影,至少在OData v3中是这样。投影更多地用于减少您需要使用的属性数量,而不是操纵属性值。

所以这很好并且支持:

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

但是只要将.Where子句放在Allocations上,就无法将其转换为OData URL语法。