• 使用linq语句进行联表查询


    假设你有一个父表(例如:汽车),其关联一个子表,例如轮子(一对多)。现在你想对于所有的父表汽车,遍历所有汽车,然后打印出来所有轮子的信息。默认的做法将是:

    SELECT CarId FROM Cars;

    然后对于每个汽车:

    SELECT * FROM Wheel WHERE CarId = ?

    这会SELECT 2个表一共N(主表的行数)+1(父表)次,故称为SELECT N+1问题。

    考察下面的代码。假设ProvinceMeeting是一个会议表,MeetSign是另外一个会议签到表,ProvinceMeeting和MeetSign是一对多的关系:

    不推荐的写法

                            var Ids = container.ProvinceMeeting.Select(f => f.Id).ToList();
                            var SignEntities = container.MeetingSign.ToList();
                            foreach (var Id in Ids)
                            {
                                var sign = container.MeetingSign.Where(f => f.MeetingId == Id);
                            }

    每次循环都会连接数据库,执行一条sql语句,select N + 1问题,很消耗性能。

    改善后的写法:

                           //这是我曾经的写法,先遍历获取主表和所有的子表数据存储在数组中,然后再foreach循环查询取出每个主表对应的子表信息, 
                            var Entities = container.ProvinceMeeting.ToList();
                            var SignEntities = container.MeetingSign.ToList();
                            foreach (var item in Entities)
                            {
                                var sign = SignEntities.Where(f => f.MeetingId == item.Id);
                            }

    我们知道foreach会强制LINQ执行,于是,我们可以想象这也是一个SELECT N+1问题的例子:先获得所有ProvinceMeeting(SELECT * FROM ProvinceMeeting),然后遍历,再去SELECT 表MeetingSign,共SELECT N+1次。(当然这里我把数据都啦取出来,储存在内存中,进行操作相当也查询了两次,但随后我还要遍历循环操作数组)。

    解决方法:使用一个匿名对象作为中间表格,预先将两个表join到一起

    最佳写法:

    var  results = container.ProvinceMeeting.Select(f => new { f.Id, son = f.MeetingSign });

    我们对结果添加监听,执行效果如下:

    主表和子表对应的关联数据,绑定在了一起,不止代码简单,执行效率也高出了不少!

  • 相关阅读:
    C#小型资源管理器
    C#换肤LrisSkin
    面向对象的24种设计模式
    七大设计原则
    非泛型集合和泛型集合
    C#经理评价系统
    深入C#.NET框架
    C#窗口航空总结
    java基础数据结构和语法
    HTML
  • 原文地址:https://www.cnblogs.com/likui-bookHouse/p/9619960.html
Copyright © 2020-2023  润新知