1

サイトの簡単な検索機能を構築しています。目的は、ユーザーが「スイマー」を見つけて、「ボブ スタッフ」のようなクエリを使用して、検索ボックスからリストに追加できるようにすることです。

私が取り組むことにした最初の部分は、ユーザーがグループ名で検索できるようにすることでした (データベースでは、すべてのスイマーはグループの一部です)。以下は、私が現時点で持っているコードです。

[HttpGet]
    public JsonResult searchForSwimmers(string q)
    {
        //designed to return [{name='foo',id='bar'}]

        String[] QueryTerms = q.Split(' '); //all the search terms are sep. by " "
        var groupResults = _db.SwimGroups.Where(g => g.Name.ContainsAny(QueryTerms)) 
            .OrderByDescending(g => g.Name.StartsWithAny(QueryTerms) ? 1 : 0)
            .ThenBy( g => g)
            .Select(g => new { name = g.Name, id = g.ID });


        return Json(groupResults,JsonRequestBehavior.AllowGet);
    }

8 行目には、 StartsWithAnyというメソッドが呼び出されています。これは、次のファイルで定義した拡張メソッドです。

public static class StringUtils
    {
     public static Boolean StartsWithAny(this String str, params String[] Fragments)
        {
            foreach (String fragment in Fragments)
            {
                if (str.StartsWith(fragment))
                {
                    return true;
                }
            }
            return false;
        }
    }

名前がいずれかの用語で始まる場合、関連性が高くランク付けされる必要があるという考えです。このロジックは素朴で欠陥があることは認識していますが、私が抱えている問題を説明する良い例になると思いました. ただし、cshtml ページで次のように searchForSimmers が呼び出されると、コードはコンパイルされます: (tokenInput ライブラリを使用)

<script type="text/javascript">
     $(document).ready(function () {
          $("#demo-input-local").tokenInput("/Admin/searchForSwimmers");
     });
</script>

500 内部サーバー エラーが発生します。エラーメッセージは次のとおりです。

LINQ to Entities does not recognize the method 'Boolean ContainsAny(System.String, System.String[])' method, and this method cannot be translated into a store expression.

ContainsAny メソッド

public static Boolean ContainsAny(this String str, List<String> Fragments)
        {
            foreach (String fragment in Fragments)
            {
                if(str.Contains(fragment))
                {
                    return true;
                }
            }
            return false;
        }

私は周りを見回しましたが、問題の解決策を見つけることができませんでした。どんな助けでも大歓迎です、乾杯。

4

2 に答える 2

2

これは、独自のメソッドContainsAnyStartsWithAny拡張メソッドも SQL に変換できないためです。

データベース テーブルが小さいため (コメントに記載されているように)、and.ToList()を実行する前に呼び出して、クエリを解決するだけです。WhereOrderBy

これを試して:

var groupResults = _db.SwimGroups
        .ToList() //evaluate the query, bring it into memory
        .Where(g => g.Name.ContainsAny(QueryTerms)) 
        .OrderByDescending(g => g.Name.StartsWithAny(QueryTerms) ? 1 : 0)
        .ThenBy( g => g)
        .Select(g => new { name = g.Name, id = g.ID });
于 2013-04-25T12:45:15.067 に答える