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 先设定好查询方式 只有在需要的时候才去作查询!


<<:  云端部署模型(Cloud deployment model)

>>:  如何提高CDN缓存命中率?

Day25. Form 里面还有 Form 怎麽办?- 表单 part3

Day23 的弹跳视窗元件,送出表单按钮在form标签的外面,理当来说form 外面的送出表单按钮和...

Day-12 函式与变数

承前文,在函式中的结构中,包括变数。使用变数,就须宣告,因此宣告所及的范围(Scope)成为函式、乃...

Day 6 - Using ASHX File for User Authorization Management with ASP.NET Web Forms C# 使用泛型处理常式进行权限分流

=x= 🌵 网页操作权限分流处理及 Yacht Manager - Master Page 後台主版...

「Wordpress 外挂开发」替你的上帝下订单,上帝模式撰写

我们最後一个主题,也是基於woocommerce,要制作出可以在bill的部分制作出可以代替别人制做...

GCP NAT

GCP NAT 前几天有提到了GKE GCP中的Private VM,这点顾名思义表示着建立起的VM...