• 兰妮   2014/7/26 11:30:00
  • 初学者必看-Linq基础语法大全
  • 关键字: linq 语法 分组
  • 一、LINQ查询符列表

    Query Operators

    Meaning in Life

    from, in

    Used to define the backbone for any LINQ expression, which allows you to extract a subset of data from a fitting container.

    where

    Used to define a restriction for which items to extract from a container.

    select

    Used to select a sequence from the container.

    join, on, equals, into

    Performs joins based on specified key. Remember, these joins do not need to have anything to do with data in a relational database.

    orderby, ascending, descending

    Allows the resulting subset to be ordered in ascending or descending order.

    group, by

    Yields a subset with data grouped by a specified value.


    另外还有一些没有操作符号,而是以扩展函数(泛型函数)的方式提供的函数:

    用不同方式产生结果集: Reverse<>(), ToArray<>(), ToList<>() 

    集合操作: Distinct<>(), Union<>(), Intersect<>()

    统计函数: Count<>(), Sum<>(), Min<>(), Max<>()

    二、使用Enumerable获取Counts

    为了使用这些Enumerable扩展函数,一般把LINQ查询表达式用括号括起来,先转换为IEnumerable<T>兼容的对象。

    static void GetCount()
    {
    string[] currentVideoGames = {"Morrowind""BioShock"
    ,
    "Half Life 2: Episode 1""The Darkness"
    ,
    "Daxter""System Shock 2"
    };
    // Get count from the query.

    int numb = (from g in currentVideoGames
    where g.Length > 6

    orderby g
    select g).Count
    <string>();
    // numb is the value 5.

    Console.WriteLine("{0} items honor the LINQ query.", numb);
    }

    三、定义演示的实例

    class Car
    {
    public string PetName = string
    .Empty;
    public string Color = string
    .Empty;
    public int
     Speed;
    public string Make = string
    .Empty;
    public override string
     ToString()
    {
    return string.Format("Make={0}, Color={1}, Speed={2}, PetName={3}"
    ,
    Make, Color, Speed, PetName);
    }
    }

    static void Main(string[] args)
    {
    Console.WriteLine(
    "***** Fun with Query Expressions *****"n"
    );
    // This array will be the basis of our testing

    Car[] myCars = new [] {
    new Car{ PetName = "Henry", Color = "Silver", Speed = 100, Make = "BMW"
    },
    new Car{ PetName = "Daisy", Color = "Tan", Speed = 90, Make = "BMW"
    },
    new Car{ PetName = "Mary", Color = "Black", Speed = 55, Make = "VW"
    },
    new Car{ PetName = "Clunker", Color = "Rust", Speed = 5, Make = "Yugo"
    },

    new Car{ PetName = "Hank", Color = "Tan", Speed = 0, Make = "Ford"
    },
    new Car{ PetName = "Sven", Color = "White", Speed = 90, Make = "Ford"
    },
    new Car{ PetName = "Mary", Color = "Black", Speed = 55, Make = "VW"
    },
    new Car{ PetName = "Zippy", Color = "Yellow", Speed = 55, Make = "VW"
    },
    new Car{ PetName = "Melvin", Color = "White", Speed = 43, Make = "Ford"
    }
    };
    // We will call various methods here!

    Console.ReadLine();
    }

    四、LINQ语法

    基本语法
    var result =  from item 
                      in container 
                      orderby value ascending/descending 
                      select item;


    1、获取全部记录
    var allCars = from c in myCars select c;


    2、只获取字段名称
    var names = from c in myCars select c.PetName;
    这里names就是隐式类型的变量。


    3、使用Enumerable.Distinct<T>()
    var makes = (from c in myCars select c.Make).Distinct<string>();



    4、即可以在定义的时候调用Enumberalbe扩展函数
    var names = from c in myCars select c.PetName;
    foreach (var n in
     names)
    {
    Console.WriteLine(
    "Name: {0}"
    , n);
    }

    也可以在兼容的数组类型上调用
    var makes = from c in myCars select c.Make;
    Console.WriteLine(
    "Distinct makes:"
    );
    foreach (var m in makes.Distinct<string>
    ())
    {
    Console.WriteLine(
    "Make: {0}"
    , m);
    }

    // Now get only the BMWs.
    var onlyBMWs = from c in myCars where c.Make == "BMW" select c;

    // Get BMWs going at least 100 mph.
    var onlyFastBMWs = from c in myCars
    where c.Make == "BMW" && c.Speed >= 100

    select c;

    5、生成新的数据类型(投影)
    var makesColors = from c in myCars select new {c.Make, c.Color};

    6、Reverse<T>()
    var subset = (from c in myCars select c).Reverse<Car>();
    foreach (Car c in subset)
    {
    Console.WriteLine("{0} is going {1} MPH", c.PetName, c.Speed);
    }

    或者
    var subset = from c in myCars select c;
    foreach (Car c in subset.Reverse<Car>
    ())
    {
    Console.WriteLine(c.ToString());
    }

    7、排序
    默认是ascending
    // Order all the cars by PetName.
    var subset = from c in myCars orderby c.PetName select c;

    // Now find the cars that are going less than 55 mph,
    // and order by descending PetName

    subset = from c in myCars
    where c.Speed > 55 orderby c.PetName descending select c;

    默认顺序时也可以明确指明
    var subset = from c in myCars
    orderby c.PetName ascending select c;

    8、Enumerable.Except()

    两个IEnumerable<T>兼容的对象的差集

    static void GetDiff()
    {
    List
    <string> myCars = new List<String>

    "Yugo""Aztec""BMW"};
    List
    <string> yourCars = new List<String>

    "BMW""Saab""Aztec" };
    var carDiff 
    =(from c in
     myCars select c)
    .Except(from c2 
    in
     yourCars select c2);
    Console.WriteLine(
    "Here is what you don't have, but I do:"
    );
    foreach (string s in
     carDiff)
    Console.WriteLine(s); 
    // Prints Yugo.

    }

    五、使用LINQ查询结果

    如果查询结果是强类型的,如string[],List<T>等,就可以不用var类型,而是使用合适的IEnumerable<T>或IEnumerable(因为IEnumerable<T>也扩展了IEnumerable)类型。
    class Program
    {
    static void Main(string
    [] args)
    {
    Console.WriteLine(
    "***** LINQ Transformations *****"n"
    );
    IEnumerable
    <string> subset =
     GetStringSubset();
    foreach (string item in
     subset)
    {
    Console.WriteLine(item);
    }
    Console.ReadLine();
    }
    static IEnumerable<string>
     GetStringSubset()
    {
    string[] currentVideoGames = {"Morrowind""BioShock"
    ,
    "Half Life 2: Episode 1""The Darkness"
    ,
    "Daxter""System Shock 2"
    };
    // Note subset is an IEnumerable<string> compatible object.

    IEnumerable<string> subset = from g in currentVideoGames
    where g.Length > 6

    orderby g
    select g;
    return subset;
    }
    }


    只有该函数原型返回类型是IEnumerable<string>,才可以使用var定义返回结果集类型。

    但是在投影操作中,由于结果集合类型是隐式的,在编译时才能确定,所以这里强制规定必须使用var
    // Error! Can't return a var data type!
    static var GetProjectedSubset()
    {
    Car[] myCars 
    = new
     Car[] {
    new Car{ PetName = "Henry", Color = "Silver", Speed = 100, Make = "BMW"
    },
    new Car{ PetName = "Daisy", Color = "Tan", Speed = 90, Make = "BMW"
    },
    new Car{ PetName = "Mary", Color = "Black", Speed = 55, Make = "VW"
    },
    new Car{ PetName = "Clunker", Color = "Rust", Speed = 5, Make = "Yugo"
    },
    new Car{ PetName = "Melvin", Color = "White", Speed = 43, Make = "Ford"
    }
    };

    var makesColors 
    = from c in myCars select new
     { c.Make, c.Color };
    return makesColors; // Nope!

    }

    可以使用ToArray<T>()把投影结果集转化为标志的CRL数组对象:
    // Return value is now an Array.
    static Array GetProjectedSubset()
    {
    Car[] myCars 
    = new
     Car[]{
    new Car{ PetName = "Henry", Color = "Silver", Speed = 100, Make = "BMW"
    },
    new Car{ PetName = "Daisy", Color = "Tan", Speed = 90, Make = "BMW"
    },
    new Car{ PetName = "Mary", Color = "Black", Speed = 55, Make = "VW"
    },
    new Car{ PetName = "Clunker", Color = "Rust", Speed = 5, Make = "Yugo"
    },
    new Car{ PetName = "Melvin", Color = "White", Speed = 43, Make = "Ford"
    }
    };
    var makesColors 
    = from c in myCars select new
     { c.Make, c.Color };
    //
     Map set of anonymous objects to an Array object.
    //
     Here were are relying on type inference of the generic
    // type parameter, as we don't know the type of type!

    return makesColors.ToArray();
    }

    然后,就可以这样使用:
    Array objs = GetProjectedSubset();
    foreach (object o in
     objs)
    {
    Console.WriteLine(o); 
    // Calls ToString() on each anonymous object.

    }

    注意:

    1、不能给ToArray<T>()指定类型,因为这里是隐式类型,到编译时才可用。
    2、不能使用System.Array 的定义语法,只能使用该对象,同样因为隐式类型。
    3、当需要使用投影的查询结果集时,把其转换为Array类型是必须的,当然这样会丢失强类型的好处。