拼吾爱程序人生.Net编程Linq LINQ查询关键字使用之from,group,select,into,where(C#)

1  /  1  页   1 跳转 查看:1238

LINQ查询关键字使用之from,group,select,into,where(C#)

LINQ查询关键字使用之from,group,select,into,where(C#)

文/worksguo  出处/博客园

我知道的关于LINQ的工具
linqpad: http://www.linqpad.net/
QueryVisualizer:http://www.scottgu.com/blogposts/linqquery/SqlServerQueryVisualizer.zip
VLinq:http://code.msdn.microsoft.com/vlinq

--------------------------------------------------------------------------------
From
--------------------------------------------------------------------------------
from:一个查询表达式的开始,如果有子查询也由它开始,指向数据源.有一个本地范围变量(range variable)来表示来源数据.他们都是强类型的.而这里的from引用的数据源必须有一个IEnumerable, IEnumerable(T)类型,或IQueryable(T).

这里提到的范围变量,就是编译器可以在当数据源实现IEnumerable(T)类型时推断这个范围变量的类型,如果源数据已有类型为IEnumerable(T),之后这个范围变量就在会被使用时推断变量类型.这里如果你的源数据没有指定泛性的IEnumerable类型,那你只有明确的指定变量类型.

下面是使用LINQ查寻ArrayList,
数据源
Code


引用:
public class Student
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int[] Scores { get; set; }
    }

Console.WriteLine("an explicit type for non-generic");
            ArrayList arrList = new ArrayList();
            arrList.Add(
                    new Student { FirstName = "Svetlana", LastName = "Omelchenko", Scores = new int[] { 98, 92, 81, 60 } }
                );
            arrList.Add(
                    new Student { FirstName = "Claire", LastName = "o'Donnell", Scores = new int[] { 75, 84, 91, 39 } }
                );
            arrList.Add(
                    new Student { FirstName = "Cesar", LastName = "Garcia", Scores = new int[] { 97, 89, 85, 82 } }
                );
//Use an explicit type for non-generic collections,and query it
            var query = from Student student in arrList
              where student.Scores[0] > 90 select student;
            foreach (Student s in query)
            {
                Console.WriteLine(s.LastName + ":" + s.Scores[0]);
            }
            Console.ReadLine();


在上面就使用非泛性的IEnumerable类型的集合ArrayList,你必须明确的指定类型,在这里from Student student,就指定类型!明确指定范围变量(range variable)就同调用Cast(TResult)方法一样的效果.Cast(TResult)和OfType(TResult)都操作非泛性IEnumberable类型的标准操作符.

以前我们谈过关于IEnumerable(T),所以只看泛性形式是怎样写的(就是大家熟悉的这个事例)


引用:
class LINQQueryExpressions
{
    static void Main()
    {

        // Specify the data source.
        int[] scores = new int[] { 97, 92, 81, 60 };

        // Define the query expression.
        IEnumerable<int> scoreQuery =
            from score in scores
            where score > 80
            select score;

        // Execute the query.
        foreach (int i in scoreQuery)
        {
            Console.Write(i + " ");
        }         
    }
}


接下来我们再看是Cast(TResult)方法
它转换IEnumerable类型的元素为指定类型.他的返回类型为IEnumerable(T).其实这个方法要被延迟执行的,就是延迟到foreach使用它时候才被执行,没有被激活时返回Object里面放有所有在被激活时所有需要的所有信息.Cast(TResult)方法可以让一些不能实现IEnumerable(T)类型的类进行转换,如果ArrayList!看下面实现:


引用:
Console.WriteLine("use generic IEnumerable collections");
            IEnumerable<Student> query2 =
                    arrList.Cast<Student>().Select(arrLists => arrLists);
            foreach (Student s in query2)
            {
                Console.WriteLine(s.LastName + ":" + s.Scores[0]);
            }
            Console.ReadLine();

比较简单!

而因为Cast(TResult)只能简单转化类型的但是如果在它集合里面有不转换的它就会抛出一个异常,只不过这里我们可以使用OfType(TResult)方法来过滤不被传换的,而不用抛出一个异常!


引用:
//use Cast<T>() method
            Console.WriteLine("use Cast<T>() method");
            ArrayList fruits = new ArrayList();
            fruits.Add("apple");
            fruits.Add("mango");

            IEnumerable<string> query3 =
                fruits.Cast<string>().Select(fruit => fruit);
            foreach (string fruit in query3)
            {
                Console.WriteLine(fruit);
            }
            Console.ReadLine();


OfType(TResult)方法
基于指定类型的来过滤IEnumerable的元素.返回一个IEnumerable(T).它也同样要被延迟的.这个方法适合应用在非参数化类型的集合中,如ArrayList,因为OfType(TResult)方法扩展类型为IEnumerable.OfType(TResult)不能应用于参数化集合中IEnumerable(T).


引用:
//OfType<T>() method
            Console.WriteLine("OfType<T>() method");
            ArrayList fruits2 = new ArrayList(4);
            fruits2.Add("Mango");
            fruits2.Add("Orang2");
            fruits2.Add("Apple2");
            fruits2.Add(3.0);
            fruits2.Add("Banana2");

            IEnumerable<string> query4 = fruits2.OfType<string>();

            Console.WriteLine("Elements of type 'string' are:");

            foreach (string fruit in query4)
            {
                Console.WriteLine(fruit);
            }
            IEnumerable<string> query5 =
              fruits2.OfType<string>().Where(fruit => fruit.ToLower().Contains("n"));

            Console.WriteLine("\nThe following strings contain 'n':");
            foreach (string fruit in query5)
            {
                Console.WriteLine(fruit);
            }
            Console.ReadLine();

         

上面是过滤了不能转换成指定类的项,第二个查寻是将arraylist中包括得有字符'n'每一项输出.

接下来是多个from的内连查询


引用:
ArrayList fruits1 = new ArrayList(2);
            fruits1.Add("apple");
            fruits1.Add("Mango");
            var query7 = from string fur in fruits1
                        where fur!="apple"
                        from string fur2 in fruits2
                        where  fur2 != "Mango"
                        select new { fur, fur2 };
            foreach(var AllFruits in query7)
            {

                Console.WriteLine("fur equal to mango:" +AllFruits.fur);
                   
                Console.WriteLine("fur2 non equal to mango:" + AllFruits.fur2);
            }
            Console.ReadKey();


 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。
 您可能对 [Linq] 的这些文章也感兴趣:

在LINQ to SQL中使用Translate方法以及修改查询用SQL  深入浅出学Linq:通过Linq to SQL看Linq
LINQ体验(10)——LINQ语句之开放式并发控制和事务  LINQ体验(2)——C# 3.0新语言特性和改进(上篇)
LINQ体验(1)——Visual Studio 2008新特性  Creating custom LINQ provider using LinqExtender
在Linq to Sql中使用记录的时间戳进行检测管理并发更新时的冲突  LINQ and Pipeline Pattern
深入浅出学Linq:Linq to SQL How do I(3)  Implementing NOLOCK with LINQ to SQL and LINQ to Entities
深入浅出学Linq:Linq to SQL Table<TEntity>的获取过程  LINQ体验(13)——LINQ to SQL语句之运算符转换和ADO.NET与LINQ to SQL
LINQ查询关键字使用之from,group,select,into,where(C#)  LINQ体验(3)——C# 3.0新语言特性和改进(下篇)
LINQ体验(15)——LINQ to SQL语句之用户定义函数  LINQ to SQL的开发会停止吗?
使用 Linq 在不同类型之间转换  Linq to SQL Dynamic
LINQ to SQL公共基类  扩展LINQ to SQL以支持批量删除
 

回复:LINQ查询关键字使用之from,group,select,into,where(C#)

--------------------------------------------------------------------------------
Where,Select
--------------------------------------------------------------------------------

(1)Where:这个与SQL基本没什么不同,起一个过滤作用,能使用在group之前或之后.
(2)select:而select也基本一样,这里select是指定range variable详细信息,还有一个作用就是指定query variable(这个就在LINQ中的一般查寻的结构能看懂吧:var query variable = from string range variable in myName select range variable).


--------------------------------------------------------------------------------
Group
--------------------------------------------------------------------------------
Group返回的是一个IGrouping(TKey, TElement)的有序对象包括0个或更多个匹配分组的键值的项.
我们需要先知道IGrouping(TKey, TElement);



引用:
public interface IGrouping <TKey,TElement> : IEnumerable<TElement>,
                                            IEnumerable
{
  TKey Key { get; }    // Key applies to the subsequence as a whole
}

参数:
TKey:是在IGrouping(TKey, TElement)中key的类型,
TElement:在IGrouping(TKey, TElement)中值的类型

IGrouping(TKey, TElement)是一个IEnumerable(T)多加一个Key,而这个key在这个里面是属性,也是这个里面每一个值都有的共同的这个属性,这个key我们可以指定实体中任何存在的值.当然也可以是任何类型.下面的事例来于MSDN中的,就反射String对象中的成员,我们再将这些成员按Key分组输出.(你可以把 First()方法换成Last方法来调试,你就知道Group关键是指定这个Key).


引用:
//use IGroup
            IGrouping<MemberTypes, MemberInfo> group =
typeof(String).GetMembers().GroupBy(member => member.MemberType).First();
            Console.WriteLine("\nValues that have the key'{0}':", group.Key);
            foreach (MemberInfo mi in group)
                Console.WriteLine(mi.Name);
            Console.ReadKey();


因为IGrouping(TKey, TElement)对象由group产生,实质就是一个List,所以你必须使用foreach.而且在执行时是keySelector和ElementSelector同时存在。
这里运行时的IL
elementSelector =
{System.Func<CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student,
CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student>}
base {System.Delegate} = {System.Func<CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student,
CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student>}

keySelector = {System.Func<CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student,char>}
base {System.MulticastDelegate} = {System.Func<CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student,char>}
base {System.Delegate} = {System.Func<CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student,char>}

回到我们的Group中来看代码,
数据源:
Code


引用:
public class Student
        {
            public string First { get; set; }
            public string Last { get; set; }
            public int ID { get; set; }
            public List<int> Scores;
        }
        public static List<Student> GetStudents()
        {
            // Use a collection initializer to create the data source. Note that each element
            //  in the list contains an inner sequence of scores.
            List<Student> students = new List<Student>
        {
          new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 72, 81, 60}},
          new Student {First="Claire", Last="O'Donnell", ID=112, Scores= new List<int> {75, 84, 91, 39}},
          new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int> {99, 89, 91, 95}},
          new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {72, 81, 65, 84}},
          new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {97, 89, 85, 82}},
          new Student {First="Eugene", Last="Zabokritski", ID=116, Scores= new List<int> {96, 85, 91, 60}},
          new Student {First="Michael", Last="Tucker", ID=117, Scores= new List<int> {94, 92, 91, 91} }
        };

            return students;

        }


一般的使用


引用:
List<Student> students = GetStudents();

            var booleanGroupQuery = from student in students
                                                  group student by student.Scores.Average() >= 80;

            foreach (var studentGroup in booleanGroupQuery)
            {
                Console.WriteLine(studentGroup.Key
                                                == true ? "High averages" : "Low averages");
                foreach (var student in studentGroup)
                {
                    Console.WriteLine("  {0}, {1}:{2}",
                        student.Last, student.First, student.Scores.Average());
                }
            }


key可以是任何值


引用:
var studentQuery2 = from student in students
                                let avg = (int)student.Scores.Average()
                                group student by (avg == 0 ? 0 : avg / 100) into g
                                orderby g.Key
                                select g;

            foreach (var studentGroup2 in studentQuery2)
            {
                int temp = studentGroup2.Key * 10;
                Console.WriteLine("Students with an average between {0} and {1}",
                                            temp, temp + 10);
                foreach (var student in studentGroup2)
                {
                    Console.WriteLine("  {0}, {1}:{2}",
                student.Last, student.First, student.Scores.Average());
                }
            }


还可以使用匿名类创建混合的KEY.



引用:
// Composite Keys
            var studentQuery6 = from f in students
                                group f by new { FirstName = f.First[0], idNumeber = f.Last[0] };

            foreach (var s in studentQuery6)
            {
                Console.WriteLine(s.Key);
                foreach (var news in s)
                {
                    Console.WriteLine(news.First + "___" + news.ID + "___" + news.Last);
                }
            }


IGrouping<key,Element>得用法


引用:
//usage IGrouping<key,Element>
    IEnumerable<IGrouping<char, Student>> studentQuery4 =
                                                                    from student in students
                                                                  group student by student.Last[0];
            foreach (IGrouping<char, Student> group in studentQuery4)
            {
                Console.WriteLine(group.Key);
                foreach (Student s in group)
                {
                    Console.WriteLine("  {0}, {1}", s.Last, s.First);


                }
            }
 

回复:LINQ查询关键字使用之from,group,select,into,where(C#)

--------------------------------------------------------------------------------
Into
--------------------------------------------------------------------------------
Into就是创建一个暂时标识来保存经过selelct, group,join等处理过的数据.


引用:
ArrayList fruits2 = new ArrayList(4);
            fruits2.Add("Mango");
            fruits2.Add("Orang2");
            fruits2.Add("Apple2");
            fruits2.Add(3.0);
            fruits2.Add("Banana2");

ArrayList fruits1 = new ArrayList(2);
            fruits1.Add("apple");
            fruits1.Add("Mango");
//keyWord into

            var wordGroup1 = from string f in fruits2
                            group f by f[0] into  fruitsGroup
                            where fruitsGroup.Count()>=1
                            select new {FirstLetter = fruitsGroup.Key,
                                                Words = fruitsGroup.Count()};
            foreach (var item in wordGroup1)
            {
                Console.WriteLine("{0} has {1} element.", item.FirstLetter, item.Words);
            }
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();

            var fruitsCount = from string f in fruits1 group f by f[3]
                                        into fruitsGroups
                                        select fruitsGroups.Key;
       
            foreach (var item in fruitsCount)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("Press any key to exit.");
        Console.ReadKey();


--------------------------------------------------------------------------------
orderby
--------------------------------------------------------------------------------
orderby用来排序,指定一个key,按照这个key来排序,指定多个Key,就能出现多级别排序!在标准的查操作符,有

OrderBy,ThenBy          升序
OrderByDescending,ThenByDescending 降序
Reverse    反转

返回类型 IOrderedEnumerable<TSource>

这里我们要来谈谈IOrderedEnumerable(TElement)接口

它表示一个排序,OrderBy,ThenBy 都是扩展它。
public interface IOrderedEnumerable<TElement> : IEnumerable<TElement>,
    IEnumerable

一个IOrderedEnumerable(TElement)的对象能通过调用第一级OrderBy或OrderByDescending排序方法获得,而输入的参数是IEnumerable<TSource>,返回一个IOrderedEnumerable(TElement). ThenBy and ThenByDescending,是子级排序方法,输入的参数类型IOrderedEnumerable(TElement)为还是返回的IOrderedEnumerable(TElement).



引用:
IEnumerable<string> sortAscendingQuery = from string f in fruits2 orderby f
                                                            select f;
        foreach(string s in sortAscendingQuery)
        {
            Console.WriteLine(s);
        }
        IEnumerable<string> sortDescendingQuery = from string f in fruits2
                                                                    orderby f descending select f;
foreach (string s in sortDescendingQuery)
        {
            Console.WriteLine(s);
        }

        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
 
1  /  1  页   1 跳转

快速回复帖子

标题
禁用 URL 识别
禁用表情
禁用 Discuz!NT 代码
使用个人签名
  [完成后可按 Ctrl+Enter 无刷新发布]  

版权所有 拼吾爱程序人生    在线留言

Powered by Discuz!NT 2.1.202   Copyright © 2001-2008 Comsenz Inc. 鄂ICP备07500843号
返顶部