LINQ查询表达式(5) - LINQ Null值处理&异常处理

查询表达式中处理Null值 

  此示例演示如何处理源集合中可能的 null 值。 诸如 IEnumerable<T> 等对象集合可能包含值为 null 的元素。 如果源集合为 null 或包含值为 null 的元素,并且查询未处理 null 值,当您执行查询时将会引发 NullReferenceException。

 var query1 =
                        from c in categories
                        where c != null
                        join p in products on c.ID equals
                            (p == null ? null : p.CategoryID)
                        select new { Category = c.Name, Name = p.Name };

   在 join 子句中,只要其中一个比较键是可以为 null 的类型,您就可以在查询表达式中将另一个比较键强制转换成可以为 null 的类型。 在下面的示例中,假定 EmployeeID 是一个列,其中包含类型为 int? 的值:

            void TestMethod(Northwind db)
                {
                    var query =
                        from o in db.Orders
                        join e in db.Employees
                            on o.EmployeeID equals (int?)e.EmployeeID
                        select new { o.OrderID, e.FirstName };
                }

 在查询表达式中处理异常

  下面的示例演示如何将异常处理代码移至查询表达式外部。 仅当该方法不依赖于查询的任何本地变量时,才能这样做。

   class ExceptionsOutsideQuery
    {
        static void Main()
        {
            // DO THIS with a datasource that might
            // throw an exception. It is easier to deal with
            // outside of the query expression.
            IEnumerable<int> dataSource;
            try
            {
                dataSource = GetData();
            }
            catch (InvalidOperationException)
            {
                // Handle (or don't handle) the exception 
                // in the way that is appropriate for your application.
                Console.WriteLine("Invalid operation");
                goto Exit;
            }
            
            // If we get here, it is safe to proceed.
            var query = from i in dataSource
                        select i * i;

            foreach (var i in query)
                Console.WriteLine(i.ToString());

            //Keep the console window open in debug mode
            Exit:
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

        // A data source that is very likely to throw an exception!
        static IEnumerable<int> GetData()
        {
            throw new InvalidOperationException();
        }
    }

  在某些情况下,对在查询内引发的异常的最佳响应可能是立即停止执行查询。 请注意,try 块将 foreach 循环而不是查询本身封闭起来。 这是因为 foreach 循环是实际执行查询的场所。

class QueryThatThrows
    {
        static void Main()
        {
            // Data source.
            string[] files = { "fileA.txt", "fileB.txt", "fileC.txt" };

            // Demonstration query that throws.
            var exceptionDemoQuery =
                from file in files
                let n = SomeMethodThatMightThrow(file)
                select n;

            // Runtime exceptions are thrown when query is executed.
            // Therefore they must be handled in the foreach loop.
            try
            {
                foreach (var item in exceptionDemoQuery)
                {
                    Console.WriteLine("Processing {0}", item);
                }
            }

            // Catch whatever exception you expect to raise
            // and/or do any necessary cleanup in a finally block
            catch (InvalidOperationException e)
            {
                Console.WriteLine(e.Message);
            }

            //Keep the console window open in debug mode
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

        // Not very useful as a general purpose method.
        static string SomeMethodThatMightThrow(string s)
        {
            if (s[4] == 'C')
                throw new InvalidOperationException();
            return @"C:\newFolder\" + s;
        }
    }
    /* Output:
        Processing C:\newFolder\fileA.txt
        Processing C:\newFolder\fileB.txt
        Operation is not valid due to the current state of the object.
     */

 参考

  [1] MSDN,查询表达式Null值处理

 

posted @ 2017-03-17 10:20  水手哥  阅读(6867)  评论(0编辑  收藏  举报