C# Linq

今天 来讲讲Linq这个好用的东西吧

不过我不会着墨在他哪些方法怎么用(这个自己Google应该就可以了

而是从另外一个面向来聊聊

先上Code 今天就拿可怜的学生作为白老鼠吧

public enum Gender{    Male,    Female,}public class Student{    public string LastName { get; set; }    public string FirstName { get; set; }    public int Age { get; set; }    public Gender Gender { get; set; }}

接下来下个简单的查询

我想查年龄16岁且是女性的学生

static void Main(string[] args){    var students = new List<Student>();    var result = students        .Where(student => student.Age == 16 && student.Gender == Gender.Female)        .ToList();}

非常好~这么简单难不倒我~

但是通常真正实作上才不会让你写hardcode

所以会有个input 让你依照input去查询

我就写个class当作input进来的结果

public class QueryInput{    /// <summary>    /// 如果是空字串就不列入查询条件    /// </summary>    public string LastName { get; set; }    /// <summary>    /// 如果是空字串就不列入查询条件    /// </summary>    public string FirstName { get; set; }    /// <summary>    /// 如果是空就不列入查询条件    /// </summary>    public int? Age { get; set; }    /// <summary>    /// 如果是空就不列入查询条件    /// </summary>    public Gender? Gender { get; set; }}

这种还算简单 会有更複杂的 例如 可能要年龄大于某个值是落在某个区间

不过这个就不是这次的重点 就不特别提了

好 现在的需求是 要依照input的参数来查询

所以我常常可以看到这种程式码

static void Main(string[] args){    var students = new List<Student>();    var queryInput = new QueryInput();    var result = students;    if (string.IsNullOrWhiteSpace(queryInput.FirstName))    {        result = result.Where(student => student.FirstName == queryInput.FirstName).ToList();    }    if (string.IsNullOrWhiteSpace(queryInput.LastName))    {        result = result.Where(student => student.LastName == queryInput.LastName).ToList();    }    if (queryInput.Age.HasValue)    {        result = result.Where(student => student.Age == queryInput.Age).ToList();    }    if (queryInput.Gender.HasValue)    {        result = result.Where(student => student.Gender == queryInput.Gender).ToList();    }}

嘛..就结果来说答案是对了

但Linq有个非常重要的特性就是 延迟查询(Deferred Execution

这是什么意思呢? 就是你设定查询语句时 并不会真的去执行

只有在"需要的时候"才会去完整执行你的查询语句

例如 ToList,ToArray Foreach, First, Count...等

所以照上面的写法 如果每个查询条件都有去下 总共会跑 4次迴圈

static void Main(string[] args){    var students = new List<Student>();    var queryInput = new QueryInput();    var query = students.AsEnumerable();    if (string.IsNullOrWhiteSpace(queryInput.FirstName))    {        query = query.Where(student => student.FirstName == queryInput.FirstName);    }    if (string.IsNullOrWhiteSpace(queryInput.LastName))    {        query = query.Where(student => student.LastName == queryInput.LastName);    }    if (queryInput.Age.HasValue)    {        query = query.Where(student => student.Age == queryInput.Age);    }    if (queryInput.Gender.HasValue)    {        query = query.Where(student => student.Gender == queryInput.Gender);    }    var result = query.ToList();}

像这样 中间段其实就只是在设定查询语句而已 真正查询会在最后一行才执行

也只会跑一次迴圈而已

另外因为延迟查询的特性 如果想知道Count

var result = query.ToList();var count = query.Count();//不要这样写!var count = result.Count();

因为如果再ToList一次 他会再次查询

我们可以写个範例来看看

static void Main(string[] args){    var datas = new List<int>()    { 1,2,3,4,5};    var query = datas.Where(x => x % 2 == 0);    datas.Clear();    datas.Add(8);    var result = query.ToList();//8    datas.Clear();    var count = query.Count();//0}

现在应该对延迟查询有些概念了吧?

所以不要任意去使用ToList 先设定好查询方式 只有在需要的时候才去作查询!


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章