Подтвердить что ты не робот

Некорректное количество аргументов, предоставленных для вызова метода 'Boolean Equals

Почему я получаю исключение аргумента, говоря, что передаю неправильное количество аргументов методу string.equals?

Я передаю три аргумента, и это должно быть правильно. На самом деле он должен вызывать ошибку времени компиляции, а не время выполнения...

Вы видите ошибку?

var translations = await (from l in context.Languages
                  join t in context.Translations on l.ISO639_ISO3166 equals t.ISO639_ISO3166
                  where string.Equals(l.ApplicationName, applicationName, StringComparison.InvariantCultureIgnoreCase)
                  select new Translation
                  {
                      Key = t.Key,
                      Text = t.Text
                  }).ToListAsync();

ОБНОВЛЕНИЕ

Test Name:  GetTranslations
Test FullName:  TaaS.IntegrationTests.Tests.TranslationRepositoryTests.GetTranslations
Test Source:    C:\test\TaaS-WebApplication\TaaS.IntegrationTests\Tests\TranslationRepositoryTests.cs : line 17
Test Outcome:   Failed
Test Duration:  0:00:00,0473367

Result StackTrace:  
at System.Linq.Expressions.Expression.GetMethodBasedBinaryOperator(ExpressionType binaryType, Expression left, Expression right, MethodInfo method, Boolean liftToNull)
   at System.Linq.Expressions.Expression.Equal(Expression left, Expression right, Boolean liftToNull, MethodInfo method)
   at System.Data.Entity.Core.Objects.ELinq.LinqExpressionNormalizer.VisitMethodCall(MethodCallExpression m)
   at System.Linq.Expressions.EntityExpressionVisitor.Visit(Expression exp)
   at System.Linq.Expressions.EntityExpressionVisitor.VisitLambda(LambdaExpression lambda)
   at System.Linq.Expressions.EntityExpressionVisitor.Visit(Expression exp)
   at System.Linq.Expressions.EntityExpressionVisitor.VisitUnary(UnaryExpression u)
   at System.Linq.Expressions.EntityExpressionVisitor.Visit(Expression exp)
   at System.Linq.Expressions.EntityExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original)
   at System.Linq.Expressions.EntityExpressionVisitor.VisitMethodCall(MethodCallExpression m)
   at System.Data.Entity.Core.Objects.ELinq.LinqExpressionNormalizer.VisitMethodCall(MethodCallExpression m)
   at System.Linq.Expressions.EntityExpressionVisitor.Visit(Expression exp)
   at System.Linq.Expressions.EntityExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original)
   at System.Linq.Expressions.EntityExpressionVisitor.VisitMethodCall(MethodCallExpression m)
   at System.Data.Entity.Core.Objects.ELinq.LinqExpressionNormalizer.VisitMethodCall(MethodCallExpression m)
   at System.Linq.Expressions.EntityExpressionVisitor.Visit(Expression exp)
   at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter..ctor(Funcletizer funcletizer, Expression expression)
   at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.CreateExpressionConverter()
   at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassc.<GetResultsAsync>b__a()
   at System.Data.Entity.Core.Objects.ObjectContext.<ExecuteInTransactionAsync>d__3d`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.<ExecuteAsyncImplementation>d__9`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Utilities.TaskExtensions.CultureAwaiter`1.GetResult()
   at System.Data.Entity.Core.Objects.ObjectQuery`1.<GetResultsAsync>d__e.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Utilities.TaskExtensions.CultureAwaiter`1.GetResult()
   at System.Data.Entity.Internal.LazyAsyncEnumerator`1.<FirstMoveNextAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Data.Entity.Infrastructure.IDbAsyncEnumerableExtensions.<ForEachAsync>d__5`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at TaaS.Repository.TranslationRepository.<GetTranslationsAsync>d__2.MoveNext() in C:\_REPOSITORIES\taas-application\TaaS-WebApplication\TaaS.Repository\TranslationRepository.cs:line 20
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at TaaS.IntegrationTests.Tests.TranslationRepositoryTests.GetTranslations() in C:\_REPOSITORIES\taas-application\TaaS-WebApplication\TaaS.IntegrationTests\Tests\TranslationRepositoryTests.cs:line 45
Result Message: 
Test method TaaS.IntegrationTests.Tests.TranslationRepositoryTests.GetTranslations threw exception: 
System.ArgumentException: Incorrect number of arguments supplied for call to method 'Boolean Equals(System.String, System.String, System.StringComparison)'
4b9b3361

Ответ 1

Это ошибка времени выполнения, потому что вы, скорее всего, работаете с поставщиком запросов Linq, который принимает expression компилятор С#, созданный с вашего кода на С#, и выполняет его во время выполнения. Вероятно, провайдер не может перевести эту перегрузку с помощью Equals.

Попробуйте изменить свой запрос Linq:

(from l in context.Languages
join t in context.Translations on l.ISO639_ISO3166 equals t.ISO639_ISO3166).AsEnumerable()
.Where(l => string.Equals(l.ApplicationName, applicationName, StringComparison.InvariantCultureIgnoreCase))
.Select(new Translation
              {
                  Key = t.Key,
                  Text = t.Text
              }).ToListAsync();

Ответ 2

Прежде всего, сравнение строк SQL нечувствительно к регистру, или, скорее, наиболее общие сортировки не учитывают регистр.

Вам не нужно использовать String.Equals вообще. Попробуйте выполнить запрос без вызова String.Equals.

Если по какой-то причине запрос не смог вернуть результаты, может возникнуть проблема с аргументами или данными. Вы должны попытаться выполнить эквивалентную инструкцию SQL напрямую и проверить, есть ли соответствующие результаты.

Случай с String будет проблемой, только если базовая сортировка столбцов была изменена до строковой. Это было бы очень необычно. На самом деле, сложная часть позволяет LINQ to EF делать запрос с учетом регистра.

Что касается самой ошибки, это вызвано тем, что String.Equals не может быть переведено на SQL. LINQ сам по себе не выполняет запросы, это просто язык. Поставщики LINQ отвечают за перевод запросов на базовый язык и их выполнение.

Некоторые поставщики, такие как LINQ to SQL, будут анализировать все, что могут, загружать результат в память и передавать его LINQ to Object для неподдерживаемых операций. Обычно это приводит к очень низкой производительности. В вашем случае ваш запрос будет загружать все переводы в память, а затем попытаться их фильтровать.

LINQ to EF, с другой стороны, не позволяет этому предотвратить проблемы с производительностью. Запросы, которые невозможно перевести, не выполняются. String.Equals, в частности, не может быть переведен на SQL, поскольку сравнение строк контролируется определенными культурами сопоставлениями. Не существует эквивалента Инвариантной Культуре.

Если ваша таблица чувствительна к регистру, вам придется изменить сортировку, используемую для сравнения, например, < <24 > . Этот вопрос SO описывает различные способы сделать это

Ответ 3

Другой способ (если вы настаиваете на нечувствительности к регистру)

var translations = await (from l in context.Languages
                  join t in context.Translations on l.ISO639_ISO3166 equals t.ISO639_ISO3166
                  where l.ApplicationName.Equals(applicationName,StringComparison.CurrentCultureIgnoreCase)
                  select new Translation
                  {
                      Key = t.Key,
                      Text = t.Text
                  }).ToListAsync();

Примечание:

l.ApplicationName.Equals(applicationName,StringComparison.CurrentCultureIgnoreCase)

Но, скорее всего, вам это не понадобится, поскольку Linq to SQL по умолчанию

". Нечувствительность к регистру, или, вернее, наиболее общие сортировки без учета регистра..."