LINQ to Entities가 'System.String ToString ()'메소드를 인식하지 못하므로이 메소드를 상점 표현식으로 변환 할 수 없습니다.
하나의 MySQL 서버에서 SQL Server로 일부 항목을 마이그레이션하고 있지만이 코드를 작동시키는 방법을 알 수 없습니다.
using (var context = new Context())
{
...
foreach (var item in collection)
{
IQueryable<entity> pages = from p in context.pages
where p.Serial == item.Key.ToString()
select p;
foreach (var page in pages)
{
DataManager.AddPageToDocument(page, item.Value);
}
}
Console.WriteLine("Done!");
Console.Read();
}
두 번째로 들어가면 다음과 foreach (var page in pages)
같은 예외가 발생합니다.
LINQ to Entities는 'System.String ToString ()'메소드를 인식하지 못하므로이 메소드를 상점 표현식으로 변환 할 수 없습니다.
왜 이런 일이 일어나는지 아십니까?
문자열을 임시 변수에 저장 한 다음 표현식에서 사용하십시오.
var strItem = item.Key.ToString();
IQueryable<entity> pages = from p in context.pages
where p.Serial == strItem
select p;
ToString()
실제로 실행되지 않기 때문에 문제가 발생 하고 MethodGroup으로 변환 된 다음 구문 분석되어 SQL로 변환됩니다. ToString()
동등한 것이 없기 때문에 표현식이 실패합니다.
노트 :
나중에 추가 된 도우미 클래스 에 대한 Alex의 답변 도 확인하십시오 SqlFunctions
. 대부분의 경우 임시 변수가 필요하지 않습니다.
다른 사람들이 대답했듯이 .ToString이 데이터베이스로가는 도중 관련 SQL로 변환하지 못하기 때문에 중단됩니다.
그러나 Microsoft는 이와 같은 상황에서 사용할 수있는 메서드 모음 인 SqlFunctions 클래스 를 제공합니다 .
이 경우 찾고있는 것은 SqlFunctions.StringConvert입니다 .
from p in context.pages
where p.Serial == SqlFunctions.StringConvert((double)item.Key.Id)
select p;
어떤 이유로 든 임시 변수가있는 솔루션이 바람직하지 않은 경우에 좋습니다.
SqlFunctions와 유사하게 EntityFunctions ( DbFunctions에서 사용되지 않는 EF6 )도 있으며 데이터 소스 와 무관 한 다른 함수 세트 (예 : SQL에 제한되지 않음)를 제공합니다.
문제는 LINQ to Entities 쿼리에서 ToString을 호출한다는 것입니다. 이것은 파서가 ToString 호출을 동등한 SQL로 변환하려고 시도한다는 것을 의미합니다 (따라서 예외는 아닙니다).
ToString 호출을 별도의 줄로 옮기기 만하면됩니다.
var keyString = item.Key.ToString();
var pages = from p in context.entities
where p.Serial == keyString
select p;
비슷한 문제가 있었다. 엔티티 컬렉션에서 ToList ()를 호출하고 목록을 쿼리하여 해결했습니다. 컬렉션이 작 으면 옵션입니다.
IQueryable<entity> pages = context.pages.ToList().Where(p=>p.serial == item.Key.ToString())
도움이 되었기를 바랍니다.
다음과 같이 변경하면 작동합니다.
var key = item.Key.ToString();
IQueryable<entity> pages = from p in context.pages
where p.Serial == key
select p;
The reason why the exception is not thrown in the line the LINQ query is declared but in the line of the foreach
is the deferred execution feature, i.e. the LINQ query is not executed until you try to access the result. And this happens in the foreach
and not earlier.
Cast table to Enumerable
, then you call LINQ methods with using ToString()
method inside:
var example = contex.table_name.AsEnumerable()
.Select(x => new {Date = x.date.ToString("M/d/yyyy")...)
But be careful, when you calling AsEnumerable
or ToList
methods because you will request all data from all entity before this method. In my case above I read all table_name
rows by one request.
Upgrading to Entity Framework Version 6.2.0 worked for me.
I was previously on Version 6.0.0.
Hope this helps,
In MVC, assume you are searching record(s) based on your requirement or information. It is working properly.
[HttpPost]
[ActionName("Index")]
public ActionResult SearchRecord(FormCollection formcollection)
{
EmployeeContext employeeContext = new EmployeeContext();
string searchby=formcollection["SearchBy"];
string value=formcollection["Value"];
if (formcollection["SearchBy"] == "Gender")
{
List<MvcApplication1.Models.Employee> emplist = employeeContext.Employees.Where(x => x.Gender == value).ToList();
return View("Index", emplist);
}
else
{
List<MvcApplication1.Models.Employee> emplist = employeeContext.Employees.Where(x => x.Name == value).ToList();
return View("Index", emplist);
}
}
If you really want to type ToString
inside your query, you could write an expression tree visitor that rewrites the call to ToString
with a call to the appropriate StringConvert
function:
using System.Linq;
using System.Data.Entity.SqlServer;
using System.Linq.Expressions;
using static System.Linq.Expressions.Expression;
using System;
namespace ToStringRewriting {
class ToStringRewriter : ExpressionVisitor {
static MethodInfo stringConvertMethodInfo = typeof(SqlFunctions).GetMethods()
.Single(x => x.Name == "StringConvert" && x.GetParameters()[0].ParameterType == typeof(decimal?));
protected override Expression VisitMethodCall(MethodCallExpression node) {
var method = node.Method;
if (method.Name=="ToString") {
if (node.Object.GetType() == typeof(string)) { return node.Object; }
node = Call(stringConvertMethodInfo, Convert(node.Object, typeof(decimal?));
}
return base.VisitMethodCall(node);
}
}
class Person {
string Name { get; set; }
long SocialSecurityNumber { get; set; }
}
class Program {
void Main() {
Expression<Func<Person, Boolean>> expr = x => x.ToString().Length > 1;
var rewriter = new ToStringRewriter();
var finalExpression = rewriter.Visit(expr);
var dcx = new MyDataContext();
var query = dcx.Persons.Where(finalExpression);
}
}
}
I got the same error in this case:
var result = Db.SystemLog
.Where(log =>
eventTypeValues.Contains(log.EventType)
&& (
search.Contains(log.Id.ToString())
|| log.Message.Contains(search)
|| log.PayLoad.Contains(search)
|| log.Timestamp.ToString(CultureInfo.CurrentUICulture).Contains(search)
)
)
.OrderByDescending(log => log.Id)
.Select(r => r);
After spending way too much time debugging, I figured out that error appeared in the logic expression.
The first line search.Contains(log.Id.ToString())
does work fine, but the last line that deals with a DateTime object made it fail miserably:
|| log.Timestamp.ToString(CultureInfo.CurrentUICulture).Contains(search)
Remove the problematic line and problem solved.
I do not fully understand why, but it seems as ToString() is a LINQ expression for strings, but not for Entities. LINQ for Entities deals with database queries like SQL, and SQL has no notion of ToString(). As such, we can not throw ToString() into a .Where() clause.
But how then does the first line work? Instead of ToString(), SQL have CAST
and CONVERT
, so my best guess so far is that linq for entities uses that in some simple cases. DateTime objects are not always found to be so simple...
Just turn the LINQ to Entity query into a LINQ to Objects query (e.g. call ToArray) anytime you need to use a method call in your LINQ query.
'Programing' 카테고리의 다른 글
주 번호에서 날짜 계산 (0) | 2020.07.07 |
---|---|
아파치를 다시 시작하지 않고 사이트의 아파치 구성을 다시로드하는 방법 (0) | 2020.07.07 |
IntelliJ IDEA 프로젝트 SDK를 설정하는 방법 (0) | 2020.07.06 |
장고 수정 관리자 복수 (0) | 2020.07.06 |
'.'는 무엇입니까 (0) | 2020.07.06 |