2011-12-20 13 views
1

私はLevenshtein Distance Linqの選択クエリ(以下に示す)を使用しようとしていますが、例外をスローします。エンティティへのLinq:メソッドを認識しません

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エンティティへ メッセージ= LINQユーザコードによって未処理であった方法を認識しない「のInt32レーベンシュタイン距離(可能System.String、可能System.String)」方法、及びこの方法は、店舗に翻訳することができません表現。 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

ありがとうございます。それは動作します。感謝。 –

関連する問題