2011-12-20 5 views
1

Levenshtein Distance Linq 선택 쿼리를 사용하려고합니다 (아래 그림 참조). 예외가 발생합니다.Linq to Entities : 메서드를 인식하지 못합니다.

IEnumerable<Host> closeNeighbours = (from h in _dbContext.People 
             let lD = Utilities.LevenshteinDistance(lastName, h.LastName) 
             let length = Math.Max(h.LastName.Length, LastName.Length) 
             let score = 1.0 - (double)lD/length 
             where score > fuzziness 

             select h); 



public static int LevenshteinDistance(string src, string dest) 
{ 
    int[,] d = new int[src.Length + 1, dest.Length + 1]; 
    int i, j, cost; 
    char[] str1 = src.ToCharArray(); 
    char[] str2 = dest.ToCharArray(); 

    for (i = 0; i <= str1.Length; i++) 
    { 
     d[i, 0] = i; 
    } 
    for (j = 0; j <= str2.Length; j++) 
    { 
     d[0, j] = j; 
    } 
    for (i = 1; i <= str1.Length; i++) 
    { 
     for (j = 1; j <= str2.Length; j++) 
     { 

      if (str1[i - 1] == str2[j - 1]) 
       cost = 0; 
      else 
       cost = 1; 

      d[i, j] = 
       Math.Min(
        d[i - 1, j] + 1,    // Deletion 
        Math.Min(
         d[i, j - 1] + 1,   // Insertion 
         d[i - 1, j - 1] + cost)); // Substitution 

      if ((i > 1) && (j > 1) && (str1[i - 1] == 
       str2[j - 2]) && (str1[i - 2] == str2[j - 1])) 
      { 
       d[i, j] = Math.Min(d[i, j], d[i - 2, j - 2] + cost); 
      } 
     } 
    } 

    return d[str1.Length, str2.Length]; 
} 

작동하지 않는 것 같습니다. 어떤 대안?

예외 : System.NotSupportedException는 메시지있어서 'INT32 LevenshteinDistance (선택 System.String, 선택 System.String)'방법 및이 방법을 인식하지 않는 엔티티 = LINQ는 저장소로 번역 할 수없는 사용자 코드에 의해 처리되지 않은이었다 표현. Source = System.Data.Entity

답변

3

EF에서 해당 함수를 적절한 TSQL로 변환 할 수 없으므로 엔티티 프레임 워크 쿼리에서이 함수를 사용할 수 없습니다. 원본 시퀀스를 메모리로 가져와 데이터베이스에 적용 할 수있는 필터를 허용 한 다음 linq-to-objects에서 나머지를 수행해야합니다. 그것은 단지 미묘한 변화 일뿐입니다.

var closeNeighbors = from h in db.People.AsEnumerable() // bring into memory 
        // query continued below as linq-to-objects 
        let lD = Utilities.LevenshteinDistance(lastName, h.LastName) 
        let length = Math.Max(h.LastName.Length, LastName.Length) 
        let score = 1.0 - (double)lD/length 
        where score > fuzziness 
        select h; 

AsEnumerable() 이전은 데이터베이스에서 발생합니다. 일반적으로 People에 적용 할 수있는 필터가있는 경우 AsEnumerable() 호출 전에 필터를 사용할 수 있습니다. 예

var mixedQuery = db.People 
        .Where(dbPredicate).OrderBy(dbOrderSelector) // at the database 
        .AsEnumerable() // pulled into memory 
        .Where(memoryPredicate).OrderBy(memoryOrderSelector); 
+0

고마워요. 그것은 효과가있다. 감사합니다. –

관련 문제