我有一個 IDictionary 的擴展,旨在允許它在執行包含時不區分大小寫:
public static bool ContainsKeyIgnoreCase<TKey, TModel>(this IDictionary<TKey, TModel> dictionary, TKey key)
{
bool? keyExists;
var keyString = key as string;
if (keyString != null)
{
keyExists =
dictionary.Keys.OfType<string>()
.Any(k => string.Equals(k, keyString, StringComparison.OrdinalIgnoreCase));
}
else
{
keyExists = dictionary.ContainsKey(key);
}
return keyExists ?? false;
}
但在 .Where() 內部,它似乎永遠不會運行,遇到斷點或任何東西:
public IEnumerable<TModel> PopulateIdsFromExistingRowsAndReturnNewRowsToCreate<TFromDBDto, TKey, TModel>(
IEnumerable<TFromDBDto> fromDatabase,
IDictionary<TKey, TModel> fromImport,
Func<TFromDBDto, TKey> keySelector)
where TFromDBDto : class, IGuidDataTransferObject
where TModel : class, IModel<Guid>
{
var groupedItems = fromDatabase
.GroupBy(i => keySelector(i));
var onlyKeys = groupedItems.Select(i => new { key = i.Key, value = i.First() });
var filtered = onlyKeys.Where(i => fromImport.ContainsKeyIgnoreCase(i.key));
var items = filtered.ToDictionary(i => i.key, i => i.value);
var newItems = fromImport
.Where(i => !items.ContainsKeyIgnoreCase(i.Key))
.Select(i => i.Value);
fromImport
.Where(i => items.ContainsKeyIgnoreCase(i.Key))
.ForEach(i => { i.Value.ID = items.AtKey(i.Key).ID; });
return newItems;
}
但是,如果在 for 回圈中,它將運行:
foreach(var keys in onlyKeys)
{
fromImport.ContainsKeyIgnoreCase(keys.key);
}
想知道我是否做錯了什么,或者只是為什么它會拒絕實際運行擴展。
uj5u.com熱心網友回復:
繼續我的評論,正如@Kirk Woll 所指出的,這是“延期執行”的一個例子。簡而言之,Where方法的執行會延遲到您需要該資料為止。
在您的情況下,您有以下代碼:
var newItems = fromImport
.Where(i => !items.ContainsKeyIgnoreCase(i.Key))
.Select(i => i.Value);
fromImport
.Where(i => items.ContainsKeyIgnoreCase(i.Key))
.ForEach(i => { i.Value.ID = items.AtKey(i.Key).ID; });
return newItems;
在執行的這一刻,沒有什么可以訪問資料本身,您確實回傳了它,但沒有進行互動。
如果您創建并測驗此示例(斷點位于回傳位置):
Dictionary<string, int> dict = new Dictionary<string, int>();
dict.Add("a", 0);
dict.Add("b", 0);
dict.Add("c", 0);
dict.Add("A", 0);
dict.Add("B", 0);
dict.Add("C", 0);
var newItems = dict
.Where(i => {
return !dict.ContainsKeyIgnoreCase(i.Key);
})
.Select(i => i.Value);
Thread.Sleep(10000);
Console.WriteLine(newItems.Count());
您將看到斷點直到 10 秒標記才會被命中(在此螢屏截圖中掠奪:https ://imgur.com/a/uPaAOvS )
至于您對斷點的評論永遠不會被擊中,請確保您回傳對可列舉而不是副本的參考,并且如果您實際與之互動。
作為一個粗略的解決方案,您可以對代碼進行以下更改:
var newItems = fromImport
.Where(i => !items.ContainsKeyIgnoreCase(i.Key))
.Select(i => i.Value)
.ToList();
這將強制執行您的查詢,因為需要將資料復制到新串列中
uj5u.com熱心網友回復:
沒有處理查詢:
fromImport
.Where(i => items.ContainsKeyIgnoreCase(i.Key))
.ForEach(i => { i.Value.ID = items.AtKey(i.Key).ID; });
ForEach() 擴展方法的定義是什么?可能是 ForEach() 正在回傳一個迭代器 (IEnumerable<>); 你需要用它來處理查詢。例如:
var myStuff = fromImport
.Where(i => items.ContainsKeyIgnoreCase(i.Key))
.ForEach(i => { i.Value.ID = items.AtKey(i.Key).ID; })
.ToList(); // <-- this will run the query
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/482045.html
上一篇:.net核心反序列化xml回應
