我在用着 ...
tmpLst = (from e in App.lstAllChilds where e.Id == Id select e).ToList();
列表在哪里lstAllChilds
,其中还包含一些损坏的数据。
所以现在我想在这个查询中处理 Try-Catch 块。
请帮忙。
我在用着 ...
tmpLst = (from e in App.lstAllChilds where e.Id == Id select e).ToList();
列表在哪里lstAllChilds
,其中还包含一些损坏的数据。
所以现在我想在这个查询中处理 Try-Catch 块。
请帮忙。
如果您只想忽略“坏元素”,那么:
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;
}
}
}
}
Here is the simplest change you can make to simply exclude items which are null or are raising an exception.
tmpLst = App.lstAllChilds.Where(e =>
{
try
{
return e != null && e.Id == Id;
}
catch
{
return false;
}
}).ToList();
But in my opinion you probably should investigate and solve the underlying problem. This doesn't seem like a scenario where exceptions should be expected.
所以,事情就是这样。有语言集成查询(Linq),然后有产生的枚举(又名迭代器)。
Linq 允许您定义一个表达式树,该树稍后由可能是也可能不是 C# 的东西执行(例如,表达式可以被翻译成 SQL 查询)。如果您正在编写 linq,则很有可能您的查询提供程序(执行表达式转换的东西)不支持异常处理(更不用说您正在做的任何事情都会引发异常)。
另一方面,Interators(或“linq to objects”)最终会在 C# 中执行,因此您可以疯狂地处理异常。
例如 w/ linq to objects 你可以这样做:
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,并且您只想跳过源 IEnumerable 引发异常的元素,请查看 Vladimir Gondarev 的回答。
然而,需要理解的重要一点是,我们刚刚传递给 Select 调用的匿名函数不是 Expression(未编译的表达式树),而是 Func(指向已编译 c# 代码的委托),这意味着它将运行在 .Net 进程中,即使我们将 myList 替换为 linq to entity 表(或其他一些 linq 提供程序)。原因是 C# 表达式语法不支持块,也不支持 try-catch。不出所料,SQL 风格的 Linq 语句(来自 xxx select yyy)也不支持 try-catch 块。
但是,仅仅因为 C# 表达式语法不支持它并不意味着您不能这样做。但是,需要明确的是,我不建议这样做,因为我非常怀疑是否存在支持它的 QueryProvider(除了 linq to objects 提供程序)。对于好奇的人,这里是如何创建一个包含 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 时,您可以使用它。
这取决于您到底要达到什么目标:
返回除“损坏”项目之外的列表。
您可以尝试使用Where
子句来检查和过滤它们:
App.lstAllChilds.Where(x => IsValidNode(x, Id)).ToList();
显然你需要实现IsValidNode
which 应该检查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;
}
如果有任何损坏的项目,则返回一个空列表。