Ладно, здесь немного.
Я пытаюсь передать Func<>
в качестве запроса, и я получаю ошибку Ошибка 1025 поставщика данных.NET Framework 2.0:
IEnumerable <Results> GetByPredicate(Func<Message, bool> predicate) {
DataContext.Threads.Where(<some criteria>)
.Select(m => m.Messages.Where(predicate));
}
// usage
GetByPredicate(message => message.Delivered == false);
GetByPredicate(message => message.Received == true);
// and so on
m.Messages
отображается как ICollection<Message>
и m.Messages.Where(predicate)
отказывается принимать Expression<Func<Message, bool>>
.
Выполнение этого результата приводит к ошибке 1025, тогда как замена предиката inline работает нормально:
IEnumerable <Results> GetByPredicate(Func<Message, bool> predicate) {
DataContext.Threads.Where(<some criteria>)
.Select(m => m.Messages.Where(message => message.Delivered == false));
}
Может кто-нибудь объяснить, что мне не хватает?
Именно так определяются объекты Thread
, Message
:
public class Thread
{
public long Id { get; set; }
public virtual ICollection<Message> Messages { get; set; }
... more props
}
public class Message
{
public long Id { get; set; }
public virtual Thread Thread { get; set; }
... more props
}
Полное исключение:
в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.GetLambdaExpression (аргумент выражения) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.GetLambdaExpression (выведение метода MethodCallExpression, int32 argumentOrdinal) в System.Data.Entity. Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate (родитель ExpressionConverter, вызов MethodCallExpression, ref DbExpression source, ref DbExpressionBinding sourceBinding, ref DbExpression lambda) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate (родитель выражений ExpressionConverter, вызов методаCallExpression) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate (родитель выражений ExpressionConverter, вызов методаCallExpression, метод последовательности SequenceMethod) в System.Data.Entity.Core.Objects. ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate (родитель ExpressionConverter, метод CallExpression linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator
1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, ref DbExpression source, ref DbExpressionBinding sourceBinding, ref DbExpression lambda) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator
1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, ref DbExpression source, ref DbExpressionBinding sourceBinding, ref DbExpression lambda) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator
1.Translate (родитель ExpressionConverter, выражение linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression (выражение linq ) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate (родитель ExpressionConverter, вызов MethodCallExpression, ref DbExpression source, ref DbExpressionBinding sourceBinding, ref DbExpression lambda) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate (родитель выражений ExpressionConverter, вызов методаCallExpression) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate (родитель выражений ExpressionConverter, вызов методаCallExpression, метод последовательности SequenceMethod) в системе. Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConv erter parent, MethodCallExpression linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.AggregateTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator
1.Translate (родитель ExpressionConverter, выражение linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateE xpression (Expression linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, ref DbExpressionBinding binding) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate (родитель ExpressionConverter, вызов методаCallExpression, ref DbExpression source, ref DbExpressionBinding sourceBinding, ref DbExpression lambda) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate (родитель выражений ExpressionConverter, вызов методаCallExpression) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate (родитель ExpressionConverter, вызов методаCallExpression, последовательность последовательности SequenceMethodMethod ) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTr anslator.TypedTranslate (родитель ExpressionConverter, MethodCallExpression linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, ref DbExpression source, ref DbExpressionBinding sourceBinding, ref DbExpression lambda) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator
1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, ref DbExpression source, ref DbExpressionBinding sourceBinding, ref DbExpression lambda) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator
1.Translate (родитель ExpressionConverter, выражение linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.UnaryTranslator.TypedTranslate (родитель ExpressionConverter, UnaryExpression linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.ContainsTranslator.TranslateContains(ExpressionConverter parent, Expression sourceExpression, Expression valueExpression) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.ContainsTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator
1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.ContainsTranslator.TranslateContains(ExpressionConverter parent, Expression sourceExpression, Expression valueExpression) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.ContainsTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator
1.Translate (родитель ExpressionConverter, выражение) в объектах System.Data.Entity.Core.Objects. ELinq.ExpressionConverter.TranslateExpression(Expression linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, вход DbExpression) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, вход DbExpression, ссылка на привязку DbExpressionBinding) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTra nslator.OneLambdaTranslator.Translate (родитель ExpressionConverter, вызов MethodCallExpression, ref Источник DbExpression, ref DbExpressionBinding sourceBinding, ref DbExpression lambda) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate (родитель ExpressionConverter, вызов MethodCallExpression ) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate (родитель выражений ExpressionConverter, вызов методаCallExpression, последовательность SequenceMethodMethod) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate( ExpressionConverter parent, MethodCallExpression linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, ref DbExpression source, ref DbExpressionBinding sourceBinding, ref DbExpression lambda) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator
1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, ref DbExpression source, ref DbExpressionBinding sourceBinding, ref DbExpression lambda) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator
1.Translate (родитель ExpressionConverter, выражение linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression (выражение linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConver ter.MethodCallTranslator.OneLambdaTranslator.Translate (родитель ExpressionConverter, вызов MethodCallExpression, ref DbExpression source, ref DbExpressionBinding sourceBinding, ref DbExpression lambda) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, Вызов методаCallExpression) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate (родитель ExpressionConverter, вызов методаCallExpression, метод последовательности SequenceMethod) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator. TypedTranslate (родитель ExpressionConverter, метод MethodCallExpression linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.UnarySequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator
1.Translate(ExpressionConverter parent, Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.UnarySequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator
1.Translate (родитель ExpressionConverter, Expression linq) в System.Data. Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert() в System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan( Nullable1 forMergeOption) at System.Data.Entity.Core.Objects.ObjectQuery
1. <> C__DisplayClass7.b__6() в System.Data.Entity.Core.Objects.O bjectContext.ExecuteInTransaction(Func1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) at System.Data.Entity.Core.Objects.ObjectQuery
1.. <> c__DisplayClass7.b__5() в System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute(1 operation) at System.Data.Entity.Core.Objects.ObjectQuery
Func1 operation) at System.Data.Entity.Core.Objects.ObjectQuery
1.GetResults(Nullable1 forMergeOption) at System.Data.Entity.Core.Objects.ObjectQuery
1..GetEnumerator> b__0() в System.Data. Entity.Internal.LazyEnumerator1.MoveNext() at System.Linq.Buffer
1..ctor(1 source) at System.Linq.Enumerable.ToArray(IEnumerable
IEnumerable1 source) at System.Linq.Enumerable.ToArray(IEnumerable
источник1 source) at System.Linq.Enumerable.ToArray(IEnumerable
1) в Data.Helpers.MessageRepository.GetMessageDtos(Int64 userId, Int32 limit, IQueryable1 messages, Expression
message1 messages, Expression
1 orderBy) в MessageRepository.cs: строка 201 в Data.Helpers.MessageRepository.GetMessagesByPredicate(Int64 userId, предел Int32, Int64 newerThan, Int64 oldThan, предикат Expression'1) в MessageRepository.cs: строка 195 в Data.Helpers.MessageRepo sitory.GetUnreadByRecipientMessages(Int64 userId, Int32 limit, Int64 newerThan, Int64 oldThan) в MessageRepository.cs: строка 160 в Data.IntegrationTests.MessageRepositoryTests.ShouldReturnUnseenMessagesOnly() в MessageRepositoryTests.cs: строка 49
Нашел ответ - было ясно, что ELinq жаловался на отсутствие Expression<...>
и ICollection.Where
не принимал бы Expression
.
Поэтому, бросая ICollection
в IQueryable
исправлена проблема:
m => m.Messages.AsQueryable().Where(predicate) // IQueryable.Where accepts Expressions
// complete invocation
IEnumerable <Results> GetByPredicate(Func<Message, bool> predicate) {
DataContext.Threads.Where(<some criteria>)
.Select(m => m.Messages.AsQueryable().Where(predicate));
}
Может быть, есть лучший ответ, но, похоже, сейчас это проблема.
<Expression<Func<Message, bool>>