2013-11-12 3 views
1

У меня есть класс со многими отношениями, и у меня возникают проблемы с правильной фильтрацией результатов из запроса, выполненного с использованием Wcf Data Services (через класс DataServiceQuery). Эта служба предоставляет модель Entity Framework 5.Внутренний запрос внутри Wcf Services query throws 'NotSupportedException'

Этот простой запрос, например:

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) 
} 

Работает должным образом.

ответ

1

OData в $ выберите пункт (который это то, что соответствует Linq select в URL-адресе) не поддерживает прогнозы, которые преобразуют значения свойств, по крайней мере, в OData v3. Прогнозы используются больше, чтобы уменьшить количество свойств, с которыми вам нужно работать, а не манипулировать значениями свойств.

Так что это хорошо и поддерживается:

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

, но как только вы поставили условие .Where на Allocations, нет никакого способа, чтобы превратить это в синтаксисе URL OData.

+0

Ну, есть ли еще одна конструкция, которая приведет к тому, что я хочу? Например, мы хотим, чтобы первое выделение не соответствовало конкретному пользователю. Это ограничивает генерируемый sql LOT, возвращая одну строку данных для каждого устройства, вместо N строк из-за N распределений. – julealgon

+0

Не могли бы вы построить запрос по-другому? Запросить все распределения, соответствующие фильтру, и затем выбрать имена устройств, связанные с каждым распределением? Или вам также нужны устройства, у которых нет ассигнований? –

+0

Мне нужно каждое устройство в этом случае, независимо от наличия распределений. Запрос здесь полностью упрощен ... мой исходный запрос возвращает по крайней мере десяток различных свойств из некоторых отношений с устройством. – julealgon

1

пытаются проверить равенство вместо назначения

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

известить об двойной ==

+0

Исправлена ​​опечатка по вопросу, это не проблема. – julealgon

1

на самом деле вы делаете задание в вашем где заявление

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

Это была опечатка, извините. Я также обновил текст исключения, чтобы отразить свойство кода (он использовал другую тестовую строку, заметил, что сначала был «==») – julealgon

Смежные вопросы