2013-06-24 31 views
1

更常见的问题,但我怎么写LINQ Lambda表达式,以便它们将返回一个默认字符串或者只是一个空字符串,如果LINQ表达式失败或不返回任何内容。在XSLT XPath中,如果匹配失败,那么只是没有任何东西,应用程序没有崩溃,而在LINQ中,似乎有异常。我该如何让LINQ Lambda表达式像XPath一样优雅地失败?

我使用First()并尝试FirstOrDefault()。

所以例如查询可能是:

Customers.First(c=>c.id==CustId).Tasks.ToList(); 

Customers.Where(c=>c.id==CustId).ToList(); 

Model.myCustomers.Where(c=>c.id==CustId); 

无论查询,如果不返回任何记录或空那么是否有基因? ral的方法来确保查询失败优雅?

谢谢。

+0

实在没有办法,除非你编写自己的扩展方法。空处理只是当今大多数语言中最可怕的事情之一。 – Jacob

回答

1

当您访问属性时,C#中没有任何优雅内容用于传播空值。你可以创建自己的扩展方法:

public static class Extensions 
{ 
    public static TValue SafeGet<TObject, TValue>(
     this TObject obj, 
     Func<TObject, TValue> propertyAccessor) 
    { 
     return obj == null ? default(TValue) : propertyAccessor(obj); 
    } 

    public static IEnumerable<T> OrEmpty<T>(this IEnumerable<T> collection) 
    { 
     return collection ?? Enumerable.Empty<T>(); 
    } 
} 

像这样来使用:

Customers.FirstOrDefault(c => c.id==CustId).SafeGet(c => c.Tasks).OrEmpty().ToList(); 
+0

这看起来很有趣。谢谢。 “Model.myCustomers.First(c => c.id == CustId).Name”将如何使用您的代码查看? – SamJolly

+0

'Model.myCustomers.FirstOrDefault(c => c.id == CustId).SafeGet(c => c.Name)' – Jacob

+0

谢谢,这就是我正在寻找的,处理空列表和空值的通用方法值。非常感谢您的帮助,谢谢。 – SamJolly

0

唯一查询我希望抛出一个异常会是第一个(假设Customers是一个有效的收集和NOT NULL本身):

Customers.First(c=>c.id==CustId).Tasks.ToList(); 

这将抛出一个异常,如果没有客户与idCustId(您的财产和变量名称有一些套管问题)。

如果你不想抛出异常的不匹配,然后使用FirstOrDefault你提到,做一个空检查,e.g:如果没有匹配的记录

var customer = Customers.FirstOrDefault(c => c.id == CustId); 
if (customer == null) 
{ 
    // deal with no match 
    return; 
} 

var taskList = customer.Tasks.ToList(); 
+0

感谢您的帮助。所以你必须打破LINQ查询?我希望有一种表达方式。 – SamJolly

+0

你可以使用扩展方法(或简单的老式的静态帮助器方法),但很可能你会想要分解代码,因为你可能希望检测到没有匹配并分支代码来调用你的不同表示逻辑表示层。 – devdigital

1

Customers.First(c=>c.id==CustId)会崩溃。

有几种方法可以尝试找到它,如果您使用FirstOrDefault,如果找不到匹配项则返回NULL,您可以检查NULL

或者,您可以使用.Any语法检查是否有任何记录并返回boolean

+0

谢谢,任何()看起来很有趣。 – SamJolly