zoukankan      html  css  js  c++  java
  • C#3.0新增功能09 LINQ 基础05 使用 LINQ 进行数据转换

    语言集成查询 (LINQ) 不只是检索数据。 它也是用于转换数据的强大工具。 通过使用 LINQ查询,可以使用源序列作为输入,并通过多种方式对其进行修改,以创建新的输出序列。通过排序和分组,你可以修改序列本身,而无需修改这些元素本身。 但也许 LINQ 查询最强大的功能是创建新类型。 这可以在 select 子句中完成。 例如,可以执行下列任务:

    • 将多个输入序列合并为具有新类型的单个输出序列。

    • 创建其元素由源序列中每个元素的一个或多个属性组成的输出序列。

    • 创建其元素由对源数据执行的操作结果组成的输出序列。

    • 创建其他格式的输出序列。 例如,可以将数据从 SQL 行或文本文件转换为 XML。

    这只是几个例子。 当然,可以以各种方式在同一查询中组合这些转换。 此外,一个查询的输出序列可以用作新查询的输入序列。

    将多个输入联接到一个输出序列中
    可以使用 LINQ 查询创建包含元素的输出序列,这些元素来自多个输入序列。 以下示例演示如何组合两个内存中数据结构,但相同的原则可应用于组合来自 XML 或 SQL 或数据集源的数据。 假设以下两种类类型:
    class Student
    {
        public string First { get; set; }
        public string Last {get; set;}
        public int ID { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public List<int> Scores;
    }
    
    class Teacher
    {
        public string First { get; set; }
        public string Last { get; set; }
        public int ID { get; set; } 
        public string City { get; set; }
    }

    以下示例演示了查询:

     1 class DataTransformations
     2 {
     3     static void Main()
     4     {
     5         // 创建第一个数据源
     6         List<Student> students = new List<Student>()
     7         {
     8             new Student { First="Svetlana",
     9                 Last="Omelchenko",
    10                 ID=111,
    11                 Street="123 Main Street",
    12                 City="Seattle",
    13                 Scores= new List<int> { 97, 92, 81, 60 } },
    14             new Student { First="Claire",
    15                 Last="O’Donnell",
    16                 ID=112,
    17                 Street="124 Main Street",
    18                 City="Redmond",
    19                 Scores= new List<int> { 75, 84, 91, 39 } },
    20             new Student { First="Sven",
    21                 Last="Mortensen",
    22                 ID=113,
    23                 Street="125 Main Street",
    24                 City="Lake City",
    25                 Scores= new List<int> { 88, 94, 65, 91 } },
    26         };
    27 
    28         // 创建第二个数据源
    29         List<Teacher> teachers = new List<Teacher>()
    30         {                
    31             new Teacher { First="Ann", Last="Beebe", ID=945, City="Seattle" },
    32             new Teacher { First="Alex", Last="Robinson", ID=956, City="Redmond" },
    33             new Teacher { First="Michiyo", Last="Sato", ID=972, City="Tacoma" }
    34         };
    35         
    36         // 创建查询
    37         var peopleInSeattle = (from student in students
    38                     where student.City == "Seattle"
    39                     select student.Last)
    40                     .Concat(from teacher in teachers
    41                             where teacher.City == "Seattle"
    42                             select teacher.Last);
    43 
    44         Console.WriteLine("The following students and teachers live in Seattle:");
    45         // 执行查询
    46         foreach (var person in peopleInSeattle)
    47         {
    48             Console.WriteLine(person);
    49         }
    50         
    51         Console.WriteLine("Press any key to exit.");
    52         Console.ReadKey();
    53     }
    54 }
    55 /* 输出:
    56     The following students and teachers live in Seattle:
    57     Omelchenko
    58     Beebe
    59  */

    有关详细信息,请参阅 join 子句和 select 子句

    选择每个源元素的子集

    有两种主要方法来选择源序列中每个元素的子集:

    1. 若要仅选择源元素的一个成员,请使用点操作。 在以下示例中,假设 Customer 对象包含多个公共属性,包括名为 City 的字符串。 在执行时,此查询将生成字符串的输出序列。

      var query = from cust in Customers  
                  select cust.City;
    2. 若要创建包含多个源元素属性的元素,可以使用带有命名对象或匿名类型的对象初始值设定项。 以下示例演示如何使用匿名类型封装每个 Customer 元素的两个属性:

      var query = from cust in Customer  
                  select new {Name = cust.Name, City = cust.City};

    有关详细信息,请参阅对象和集合初始值设定项匿名类型

    将内存中对象转换为 XML
    LINQ 查询可以轻松地在内存中数据结构、SQL 数据库、ADO.NET 数据集和 XML 流或文档之间转换数据。 以下示例将内存中数据结构中的对象转换为 XML 元素。
     1 class XMLTransform
     2 {
     3     static void Main()
     4     {            
     5         // 使用集合初始值设定项创建数据源
     6         // 学生类是在上述定义的
     7         List<Student> students = new List<Student>()
     8         {
     9             new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores = new List<int>{97, 92, 81, 60}},
    10             new Student {First="Claire", Last="O’Donnell", ID=112, Scores = new List<int>{75, 84, 91, 39}},
    11             new Student {First="Sven", Last="Mortensen", ID=113, Scores = new List<int>{88, 94, 65, 91}},
    12         };
    13 
    14         // 创建查询
    15         var studentsToXML = new XElement("Root",
    16             from student in students
    17             let scores = string.Join(",", student.Scores)
    18             select new XElement("student",
    19                        new XElement("First", student.First),
    20                        new XElement("Last", student.Last),
    21                        new XElement("Scores", scores)
    22                     ) // end "student"
    23                 ); // end "Root"
    24 
    25         // 执行查询
    26         Console.WriteLine(studentsToXML);
    27 
    28         // Keep the console open in debug mode.
    29         Console.WriteLine("Press any key to exit.");
    30         Console.ReadKey();
    31     }
    32 }

    此代码生成以下 XML 输出:

    <Root>  
      <student>  
        <First>Svetlana</First>  
        <Last>Omelchenko</Last>  
        <Scores>97,92,81,60</Scores>  
      </student>  
      <student>  
        <First>Claire</First>  
        <Last>O'Donnell</Last>  
        <Scores>75,84,91,39</Scores>  
      </student>  
      <student>  
        <First>Sven</First>  
        <Last>Mortensen</Last>  
        <Scores>88,94,65,91</Scores>  
      </student>  
    </Root>

    有关详细信息,请参阅在 C# 中创建 XML 树 (LINQ to XML)

    对源元素执行操作

    输出序列可能不包含源序列中的任何元素或元素属性。 输出可能是使用源元素作为输入参数而计算得出的值序列。 以下简单查询在执行时会输出一串字符串,其值表示基于 double类型的元素的源序列的计算结果。

    如果查询将被转换为另一个域,则不支持在查询表达式中调用方法。 例如,不能在 LINQ to SQL 中调用普通的 C# 方法,因为 SQL Server 没有用于它的上下文。 但是,可以将存储过程映射到方法并调用这些方法。 有关详细信息,请参阅存储过程

    class FormatQuery
    {
        static void Main()
        {            
            // 数据源
            double[] radii = { 1, 2, 3 };
    
            // 查询表达式
            IEnumerable<string> query =
                from rad in radii
                select $"Area = {rad * rad * Math.PI:F2}";
    
            // 执行查询
            foreach (string s in query)
                Console.WriteLine(s);
    
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
    }
    /* 输出:
        Area = 3.14
        Area = 12.57
        Area = 28.27
    */

    其他技术请参考

  • 相关阅读:
    JavaScript
    94.Binary Tree Inorder Traversal
    144.Binary Tree Preorder Traversal
    106.Construct Binary Tree from Inorder and Postorder Traversal
    105.Construct Binary Tree from Preorder and Inorder Traversal
    90.Subsets II
    78.Subsets
    83.Merge Sorted Array
    80.Remove Duplicates from Sorted Array II
    79.Word Search
  • 原文地址:https://www.cnblogs.com/SavionZhang/p/11177563.html
Copyright © 2011-2022 走看看