복붙노트

[SQL] 엔티티 LINQ는 방법 '선택 System.String ToString () 메소드를 인식하지 않고,이 방법은 저장 식으로 변환 될 수 없다

SQL

엔티티 LINQ는 방법 '선택 System.String ToString () 메소드를 인식하지 않고,이 방법은 저장 식으로 변환 될 수 없다

나는 SQL 서버에 하나 개의 MySQL 서버에서 몇 가지 물건을 마이그레이션하고있어하지만 난이 코드가 작동하는 방법을 알아낼 수 없습니다 :

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 페이지)를 입력하면 그 말하는 예외가 발생합니다 :

이런 이유를 아는 사람?

해결법

  1. ==============================

    1.그냥 임시 변수에 문자열을 저장 한 다음 식에서 것을 사용합니다

    그냥 임시 변수에 문자열을 저장 한 다음 식에서 것을 사용합니다

    var strItem = item.Key.ToString();
    
    IQueryable<entity> pages = from p in context.pages
                               where  p.Serial == strItem
                               select p;
    

    문제는 ToString ()가 실제로 실행되지 않기 때문에이 MethodGroup로 전환 한 후 분석 및 SQL로 변환되어 발생한다. 더 ToString () 당량이 없기 때문에, 표현식은 실패한다.

    당신은 나중에 추가 된 SqlFunctions 헬퍼 클래스에 대한 알렉스의 답변을 확인해야합니다. 많은 경우에 임시 변수에 대한 필요성을 제거 할 수 있습니다.

  2. ==============================

    2.다른 사람이이 휴식을 대답 것처럼로 .toString는 데이터베이스에가는 길에 관련 SQL로 변환하지 못하기 때문에.

    다른 사람이이 휴식을 대답 것처럼로 .toString는 데이터베이스에가는 길에 관련 SQL로 변환하지 못하기 때문에.

    그러나 마이크로 소프트는이 같은 상황에서 사용할 수있는 방법의 모음입니다 SqlFunctions 클래스를 제공합니다.

    이 경우를 들어, 당신이 여기에서 찾고있는 것은 SqlFunctions.StringConvert입니다 :

    from p in context.pages
    where  p.Serial == SqlFunctions.StringConvert((double)item.Key.Id)
    select p;
    

    임시 변수와 솔루션이 어떤 이유에서 바람직하지 않을 때 좋은.

    SqlFunctions 마찬가지로 당신은 또한 (예를 들어, SQL에 국한되지 않음) (EF6은 DbFunctions에 의해 대체와 함께) 그 또한 데이터 소스 무관있는 기능의 다른 세트를 제공하는 EntityFunctions 있습니다.

  3. ==============================

    3.문제는 당신이 엔티티 질의에 LINQ하면 다음과 같이 ToString을 호출하는 것입니다. 수단은 파서 (따라서 예외 ... 불가능 함) 상당 SQL로 호출의 toString 변환하려고된다.

    문제는 당신이 엔티티 질의에 LINQ하면 다음과 같이 ToString을 호출하는 것입니다. 수단은 파서 (따라서 예외 ... 불가능 함) 상당 SQL로 호출의 toString 변환하려고된다.

    당신이 할 수있는 일은 별도의 라인에의 toString 전화를 이동할 수 있습니다 :

    var keyString = item.Key.ToString();
    
    var pages = from p in context.entities
                where p.Serial == keyString
                select p;
    
  4. ==============================

    4.비슷한 문제가 있었다. 엔티티의 컬렉션 ToList ()를 호출하고 목록을 조회하여 그것을 해결. 컬렉션이 작은 경우이 옵션입니다.

    비슷한 문제가 있었다. 엔티티의 컬렉션 ToList ()를 호출하고 목록을 조회하여 그것을 해결. 컬렉션이 작은 경우이 옵션입니다.

    IQueryable<entity> pages = context.pages.ToList().Where(p=>p.serial == item.Key.ToString())
    

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

  5. ==============================

    5.이런 식으로 변경하고 그것을 작동합니다 :

    이런 식으로 변경하고 그것을 작동합니다 :

    var key = item.Key.ToString();
    IQueryable<entity> pages = from p in context.pages
                               where  p.Serial == key
                               select p;
    

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

  6. ==============================

    6.Enumerable에서 캐스팅 테이블, 당신은 ToString () 메소드의 내부를 사용하여 LINQ 메서드를 호출 :

    Enumerable에서 캐스팅 테이블, 당신은 ToString () 메소드의 내부를 사용하여 LINQ 메서드를 호출 :

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

    이 방법 전에 모든 개체에서 모든 데이터를 요청합니다 때문에 AsEnumerable 또는 ToList 메소드를 호출 때,주의해야합니다. 내 경우에는 내가 하나 개의 요청에 의해 모든 테이블 _ 행을 읽어보다.

  7. ==============================

    7.엔티티 프레임 워크 버전 6.2.0로 업그레이드 나를 위해 일했다.

    엔티티 프레임 워크 버전 6.2.0로 업그레이드 나를 위해 일했다.

    나는 버전 6.0.0에 이전했다.

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

  8. ==============================

    8.MVC에서, 당신은 당신의 요구 사항이나 정보를 기반으로 레코드 (들)을 검색한다고 가정합니다. 그것은 제대로 작동합니다.

    MVC에서, 당신은 당신의 요구 사항이나 정보를 기반으로 레코드 (들)을 검색한다고 가정합니다. 그것은 제대로 작동합니다.

    [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);
        }         
    }
    
  9. ==============================

    9.당신이 정말로 쿼리 내에서 ToString을 입력 할 경우, 적절한 StringConvert 함수에 대한 호출로 ToString에 대한 호출을 다시 쓰는 식 트리 방문자를 작성할 수 :

    당신이 정말로 쿼리 내에서 ToString을 입력 할 경우, 적절한 StringConvert 함수에 대한 호출로 ToString에 대한 호출을 다시 쓰는 식 트리 방문자를 작성할 수 :

    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);
    
            }
        }
    }
    
  10. ==============================

    10.나는이 경우 동일한 오류가 발생했습니다 :

    나는이 경우 동일한 오류가 발생했습니다 :

    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);
    

    방법에게 너무 많은 시간 디버깅을 지출 후, 나는 논리의 표현에 등장 오류를 알아 냈어.

    첫 번째 줄의 search.Contains (log.Id.ToString ()) 잘 작동하지만, DateTime 개체와 거래는 비참하게 실패하게하는 마지막 줄을 수행합니다

    || log.Timestamp.ToString(CultureInfo.CurrentUICulture).Contains(search)
    

    문제가있는 줄을 제거하고 문제가 해결.

    하지만 엔티티에, 나는 완전히 이유를 이해하지 않습니다,하지만 ToString (으로 보이는) 문자열에 대한 LINQ 표현이다. SQL 등의 데이터베이스 쿼리와 엔티티 거래에 대한 LINQ 및 SQL이 된 toString 대한 개념이 없다 (). 따라서, 우리는 어디에요 () 절에 ToString ()을 던질 수 없습니다.

    하지만 어떻게 그 첫 번째 줄 작동합니까? 대신 ToString ()으로, SQL 내 추측 지금까지 기관의 사용을 위해 그 LINQ는 것입니다, 그래서 CAST 및 CONVERT가 몇 가지 간단한 사례이다. 날짜 시간 객체는 항상 단순하게 찾을 수 없습니다 ...

  11. ==============================

    11.그냥 개체 쿼리에 LINQ에 엔티티 질의에 LINQ를 돌려 당신이 당신의 LINQ 쿼리 메서드 호출을 사용할 필요가 언제 (예를 들어, ToArray를 호출).

    그냥 개체 쿼리에 LINQ에 엔티티 질의에 LINQ를 돌려 당신이 당신의 LINQ 쿼리 메서드 호출을 사용할 필요가 언제 (예를 들어, ToArray를 호출).

  12. from https://stackoverflow.com/questions/5899683/linq-to-entities-does-not-recognize-the-method-system-string-tostring-method by cc-by-sa and MIT license