2

EF エンティティ タイプ (人) に対して一般的な検索クエリを作成しようとしています。一般に、検索では文字列を取得し、それをコンマで分割してから、さまざまな属性にすべてのキーワードが含まれている人を検索します。

getProperties(Person p) という関数があり、エンティティ (エンティティ タイプによってオーバーライド) を受け取り、さまざまな関連プロパティを区切り記号で結合した文字列を返します。

John~Doe~Team A~Full Time

ユーザーが「Team A, Full」を検索すると、上記のフラット化されたエンティティに対応する人物が返されるはずですが、「John、Smith」と入力すると返されません。

以下は正しいように見えると思いますが、うまくいきません...

public IEnumerable<Person> SearchPeople(string searchString)
{
    if (searchString == null || string.IsNullOrEmpty(searchString.Trim()))
        return base._objectSet.ToList();

    string[] SearchWords = searchString.Split(',').Select(s => s.Trim()).ToArray();

    return (from    person 
            in      base._objectSet 
            let     t = (getProperties(person)) 
            where   SearchWords.All(word => t.Contains(word)) 
            select  person).ToList();
}

getProperties 関数は次のとおりです。

public static string getProperties(Person p)
{
    string[] values = { p.Surname, p.GivenName, p.Team, p.Status };
    return values.Aggregate((x, y) => String.IsNullOrEmpty(y) ? x : string.Concat(x, "~", y));
}

誰かが私が間違っているところを見ていますか?

編集

例外は発生しませんが、コードをステップ実行すると、linq に到達すると、クエリをホストしている unitofwork の dispose メソッドにステップ インします。非常に奇妙な。

ハードコードされた文字列に対して検索するように変更すると、期待どおりに機能します。

var test = (from    person 
            in      base._objectSet 
            where   SearchWords.All(word => "John~Doe~Team A~Full Time".Contains(word))
            select person).ToList();

まあ、それは私が期待するクエリと一致するという点で機能しますが、静的であるため、すべての人のレコードを返します (where(true) =P を持つのとほとんど同じです)

2 番目の編集

さらに奇妙なのは、結果を var に格納し、戻り時にブレークポイントを指定して var を返すと、実行がブレークポイントに到達しないことです... この linq はブラック ホールのようなものです... 踏み込むことはできますが、 SearchPeople メソッドに戻ることはありません...コンテキストを破棄し、それを忘れるだけです。

サードを編集

ToString() をすぐに呼び出さずに、デバッガーで linq 式を見ると、「Linq to Entities はメソッド getProperties(Person) を認識しません」と表示されます。 linq を窒息させずに私のメソッドを使用するには?

4

2 に答える 2

0

あなたはリストを返していますか?戻り値の型をリストにするか、変更し.ToList()てくださいAsEnumerable()

public List<Person> SearchPeople(string searchString)
{
    if (searchString == null || string.IsNullOrEmpty(searchString.Trim()))
        return base._objectSet.ToList();

    string[] SearchWords = searchString.Split(',').Select(s => s.Trim()).ToArray();

    return (from    person 
            in      base._objectSet 
            let     t = (getProperties(person)) 
            where   SearchWords.All(word => t.Contains(word)) 
            select  person).ToList();
}
于 2012-11-30T17:20:46.380 に答える
0

さて、linq 2エンティティがメソッドを好まないことを発見した後(SQLに変換する方法がわからないため)、linqは非常に面倒ですが機能する方法であると書き直しました:

var people = from    p
             in      base._objectSet
             where   SearchWords.All(p.GivenName.Contains(word) || p.Surname.Contains(word) || p.(???).Contains(word) || etc.)
                    select p;

迷惑ですが、どうぞ。

于 2012-11-30T18:29:15.070 に答える