私はユニットのテストの途中で、クエリ可能なアイテムを検索するための関数を書いています。私はちょうど私が1つのアイテムを取得することを主張する、私は方法が動作する場合、私は取得する必要があります。しかし、私は0アイテムを返す。私の方法では、遅延実行を使用し、返す前にToList
を使用します。しかし、代わりにリストを直接操作して、ToList
を繰り返し呼び出すメソッドを変更すると、正しい結果が得られます。遅延実行とToListの結果が異なる
遅延実行が即時実行と同じ結果をもたらすと想定するのは安全ではないと言うのは正しいですか?
これは私が実際に2 everything that begins with 2 should be found
はそれがないとfalseを返す、Value
が含まれている場合、それはチェックしていることがわかりますブレークポイントを設定した場合、それは0アイテム
class Program
{
static void Main(string[] args)
{
Dictionary<string, string> values = new Dictionary<string, string>()
{
{
"Prop1",
"*Value*"
},
{
"Prop2",
"2*"
}
};
List<InputItem> items =new List<InputItem>()
{
new InputItem()
};
Console.WriteLine(Helper.SearchInputItems(items.AsQueryable(), values).Count);
Console.ReadLine();
}
}
public class InputItem
{
public Dictionary<string, string> MappedValues = new Dictionary<string, string>()
{
{
"Prop1",
"This is a value that should be found"
},
{
"Prop2",
"2 everything that begins with 2 should be found"
}
};
}
public static class Helper
{
delegate bool Searcher(string input, string searchString);
/// <summary>
/// Searches the added input items.
/// </summary>
/// <param name="values">A dictionary of field names and the search pattern for that field.</param>
/// <returns>List of found InputItems.</returns>
public static List<InputItem> SearchInputItems(IQueryable<InputItem> inputItems, Dictionary<string, string> values)
{
foreach (var value in values)
{
string searchString = value.Value;
Searcher searcher;
if (searchString.StartsWith("*") && searchString.EndsWith("*"))
{
searcher = new Searcher(StringHelpers.Contains);
searchString = searchString.Substring(1);
searchString = searchString.Remove(searchString.Length - 1);
}
else if (searchString.EndsWith("*"))
{
searcher = new Searcher(StringHelpers.StartsWith);
searchString = searchString.Remove(searchString.Length - 1);
}
else
{
searcher = new Searcher(StringHelpers.Exact);
}
inputItems = inputItems.Where(c =>
c.MappedValues.Any(x => x.Key == value.Key) &&
searcher(c.MappedValues.First(x => x.Key == value.Key).Value, searchString)
);
}
return inputItems.ToList();
}
}
public static class StringHelpers
{
public static bool Contains(string input, string searchString)
{
return input.ToUpperInvariant().Contains(searchString.ToUpperInvariant());
}
public static bool StartsWith(string input, string searchString)
{
return input.ToUpperInvariant().StartsWith(searchString.ToUpperInvariant());
}
public static bool Exact(string input, string searchString)
{
return input.ToUpperInvariant() == searchString.ToUpperInvariant();
}
}
を返すことを実証するために小さなアプリです。だからWhere句のFirstOrDefaultが間違った項目を選択するように思えます
投稿したコードは* working *コードですか?それが壊れている場合、どのように見えますか?メソッドのシグネチャは 'List'を返すと言っているので、それをどのように遅延させるかを知るのは難しいですか?*入力データに 'ToList'を呼び出すことについて話していますか? –
@Jonいいえ、投稿されたコードは意図したとおりに動作していません。それが動作するとき、私は最初の行を 'var inputItems = InputItemRepository.GetInputItems()。ToList;' –
に変更します。それは完全にはっきりしていなかった。さて、InputItemRepositoryは実際に何を返すのですか?これは本当にデータベースに接続されているのですか?あなたは本当にこれを実証するためにあなたが持っているコードの量を減らすことができるはずです - あなたは本当にそれを失敗させるためにStartsWithとEndsWithの両方が必要ですか?すべてのマッピングとフィルタが必要ですか? –