Служба данных WCF $ select, возвращающая исключение «Не реализовано» - PullRequest
0 голосов
/ 20 января 2012

У меня есть проект, над которым я работаю, у которого есть сущность Order, у которой есть свойство навигации для OrderITems:

public class Order
{
   public int OrderId { get; set; }
   public int CustomerId { get; set; }

   public virtual ICollection<OrderItem> OrderItems { get; set; }
}

public class OrderItem
{
   public int OrderId { get; set; }
   public int ProductId { get; set; }
   public int Quantity { get; set; }

   public virtual Order Order { get; set; }
}

Если я запрашиваю OrderItems следующим образом:

http://mysvc.com/mysvc/OrderItems?$expand=Order&$filter=ProductId eq 1234

Это работает хорошо, но в конечном итоге мне нужно только привязать к Ордену.Итак, я хотел бы спроектировать так:

http://mysvc.com/mysvc/OrderItems?$expand=Order&$filter=ProductId eq 1234&$select=Order

Однако я получаю исключение «Не реализовано».

В этом проекте используется код EntityFramework, сначала провайдер данных 4.1, и всепроводка "кажется" правильной.Единственное, что я добавил, - это маршрутизацию для создания чистого успокоительного URI и поддержки опции $ format через IDispatchMessageInspector.

Хорошо, благодаря вводу Vitek я смог получить более полное исключение:

<error>
    <code/>
    <message xml:lang="en-US">Not Implemented</message>
    <innererror>
        <message>Unable to create a constant value of type 'System.Data.Services.Internal.ProjectedWrapper1'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.
        </message>
        <type>System.NotSupportedException</type>
        <stacktrace>   at System.Data.Objects.ELinq.ExpressionConverter.ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression linq)

           at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)

           at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)

           at System.Data.Objects.ELinq.ExpressionConverter.ConditionalTranslator.TypedTranslate(ExpressionConverter parent, ConditionalExpression linq)

           at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)

           at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)

           at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)

           at System.Data.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding& binding)

           at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& lambda)

           at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)

           at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)

           at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)

           at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)

           at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)

           at System.Data.Objects.ELinq.ExpressionConverter.Convert()

           at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)

           at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)

           at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()

           at System.Data.Entity.Internal.Linq.InternalQuery`1.GetEnumerator()

           at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.IEnumerable.GetEnumerator()

           at System.Data.Services.Internal.ProjectedWrapper.EnumerableWrapper.System.Collections.IEnumerable.GetEnumerator()

           at System.Data.Services.WebUtil.GetRequestEnumerator(IEnumerable enumerable)
           </stacktrace>
    </innererror>
</error>

1 Ответ

2 голосов
/ 24 января 2012

Если используется EF Code First, ему необходимо определить службу как DataService и переопределить CreateDataSource, чтобы использовать прием, описанный в этой статье в разделе № 5: http://social.technet.microsoft.com/wiki/contents/articles/5234.aspx

В противном случае WCF DS обрабатывает DbContextкак поставщик отражений будет и выполняет запросы, предназначенные для LINQ to Objects.Это в основном работает, но для более сложных запросов иногда ломается.Если DS WCF знает, что запускает снова EF, он создает запросы для EF, которые будут работать всегда.

...