我米使用...異常Linq中處理查詢
tmpLst = (from e in App.lstAllChilds where e.Id == Id select e).ToList();
其中lstAllChilds
是列表,其中包含了一些被破壞的數據也是如此。
所以現在我試圖在這個查詢中處理Try-Catch塊。
請幫忙。
我米使用...異常Linq中處理查詢
tmpLst = (from e in App.lstAllChilds where e.Id == Id select e).ToList();
其中lstAllChilds
是列表,其中包含了一些被破壞的數據也是如此。
所以現在我試圖在這個查詢中處理Try-Catch塊。
請幫忙。
這是您可以做出的最簡單的更改就是排除空值或引發異常的項目。
tmpLst = App.lstAllChilds.Where(e =>
{
try
{
return e != null && e.Id == Id;
}
catch
{
return false;
}
}).ToList();
但在我看來,你可能應該調查和解決根本問題。這看起來並不像預期有例外情況。
這取決於你正在努力實現的正是:
返回列表除了「破」的項目。
您可以嘗試使用Where
條款檢查並過濾掉:
App.lstAllChilds.Where(x => IsValidNode(x, Id)).ToList();
顯然,你需要實現IsValidNode
應檢查null
,如果它能夠拋出InvalidObjectException
(不知道您可以輕鬆檢測到它,但您始終可以將它包裝在try-catch塊中)和Id
等式。這樣的:
private bool IsValidNode(Child c, int id)
{
if (x == null) return false;
try {
return c.Id == id;
}
catch (InvalidObjectException)
{
}
return false;
}
返回一個空列表,如果有任何損壞的物品。
在情況下,如果你只是想忽略 「壞分子」,則:
App.lstAllChilds.SkipExceptions().Where(e => e.Id == Id).ToList();
擴展方法:
public static class Extensions
{
public static IEnumerable<T> SkipExceptions<T>(this IEnumerable<T> values)
{
using (var enumerator = values.GetEnumerator())
{
bool next = true;
while (next)
{
try
{
next = enumerator.MoveNext();
}
catch
{
continue;
}
if (next) yield return enumerator.Current;
}
}
}
}
所以,這是事情。有語言綜合查詢(Linq),然後得到枚舉(又名迭代器)。
Linq允許您定義一個表達式樹,稍後由可能或可能不是C#的東西(例如表達式可以轉換爲SQL查詢)來執行。如果你正在編寫linq,你的查詢提供者(做表達式轉換的東西)不會支持異常處理(更不用說你正在做的事情會拋出異常)。另一方面(或「對象的linq」)的交互只是最終在C#中執行,所以你可以隨意處理異常。
例如瓦特/ LINQ到對象,你可以這樣做:
var myList = new[] { "1", "2", "BARF", "3" };
var sum = myList.Select(str => {
try {
return Int32.Parse(str);
} catch {
return 0;
}
}).Aggregate((x, y) => x + y);
如果你確實做的LINQ to對象,你只是想跳過元素,其中源的IEnumerable拋出異常退房弗拉基米爾貢達列夫的回答。
但是務必要了解的重要一點是,我們只是傳遞給選擇呼叫匿名函數不是表達式(未編譯表達式樹),它是一個Func鍵(指向編譯的C#代碼爲代表),這意味着它將運行在.Net進程中,即使我們用一個linq替換myList到實體表(或其他一些linq提供程序)。原因是C#表達式語法不支持塊,也不支持try-catch。不出所料,因爲SQL風格的Linq語句(從xxx選擇yyy)也不支持try-catch塊。
但是,僅僅因爲C#表達式語法不支持它並不意味着你不能這樣做。但是,要清楚,我不建議這樣做,因爲我非常懷疑存在支持它的QueryProvider(除了linq to objects provider)。好奇的是,你將如何創建一個包含try-catch塊的lambda表達式。
var parseMethod = typeof(Int32).GetMethod("Parse", new[] { typeof(String) });
var param = Expression.Parameter(typeof(String));
var selectExp =
Expression.Lambda<Func<String, Int32>>(
Expression.TryCatch(
Expression.Call(parseMethod, param),
Expression.Catch(typeof(Exception), Expression.Constant(0))
),
param
);
var sum = myList.Select(selectExp).Aggregate((x, y) => x + y);
因此,當有人實現由支持異常處理的存儲支持的QueryProvider時,您可以使用它。
這是Linq的實體嗎? Linq到對象?什麼是'lstAllChilds'的類型?我無法理解你準確抓住什麼異常......你真的得到了一個嗎? –
我的自定義類列表...(列表 App.lstAllChilds) –
Nitin
異常是'InvalidObjectException'和'ArgumentNullException' – Nitin