[C#] 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;

LINQ 쿼리가 선언 된 행에서 예외가 발생하지 않는 이유는 foreach지연된 실행 기능입니다. 즉, 결과에 액세스하려고 할 때까지 LINQ 쿼리가 실행되지 않습니다. 그리고 이것은 foreach이전이 아니라 이전에 발생합니다 .


답변

테이블을로 캐스팅 Enumerable한 다음 ToString()내부에서 메소드를 사용하여 LINQ 메소드를 호출하십시오 .

    var example = contex.table_name.AsEnumerable()
.Select(x => new {Date = x.date.ToString("M/d/yyyy")...)

그러나이 메소드 이전에 모든 엔티티에서 모든 데이터를 요청하므로 호출 AsEnumerable또는 ToList메소드 를 호출 할 때주의하십시오 . 위의 경우에는 한 table_name번의 요청으로 모든 행을 읽습니다 .


답변

Entity Framework 버전 6.2.0으로 업그레이드하면 효과적 입니다.

이전에 버전 6.0.0에있었습니다.

도움이 되었기를 바랍니다,