003. 大表数据连接查询优化 临时表
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModelFirst
{
class Program
{
static void Main(string[] args)
{
//创建上下文
Model1Container dbContext = new Model1Container();
#region 新增数据
//创建一个用户和两个订单
//UserInfo userInfo = new UserInfo();
//userInfo.UserAddr = "珠海市";
//userInfo.UserName = "老大";
////告诉上下文要对这个实体执行添加操作
//dbContext.UserInfo.Add(userInfo);
//OrderInfo orderInfo1 = new OrderInfo();
//orderInfo1.BookAuth = "不认识";
//orderInfo1.BookName = "谈谈那些你不认识的人";
//dbContext.OrderInfo.Add(orderInfo1);
//OrderInfo orderInfo2 = new OrderInfo();
//orderInfo2.BookAuth = "亲戚";
//orderInfo2.BookName = "谈谈你的亲戚";
//dbContext.OrderInfo.Add(orderInfo2);
////第一种关联方法 将订单指定给用户实体
//orderInfo1.UserInfo = userInfo;
////第二种关联方法 通过用户添加订单实体到自己的导航属性
//userInfo.OrderInfo.Add(orderInfo2);
#endregion
#region 修改数据
//UserInfo userInfoEdit = new UserInfo();
//userInfoEdit.Id = 1;
//userInfoEdit.UserAddr = "深圳市";
//userInfoEdit.UserName = "老大";
////修改的第一种方法
//dbContext.Entry<UserInfo>(userInfoEdit).State = System.Data.Entity.EntityState.Modified;
////修改的第二种方法, 指定某个字段做修改, 这里演示的是指定UserAddr字段; 在5.0之前(不含)的版本中这样添加
////dbContext.UserInfo.Attach(userInfoEdit);
////dbContext.Entry<UserInfo>(userInfoEdit).Property(u => u.UserAddr).IsModified = true;
#endregion
#region 两种延时加载的机制
//第一种延迟加载, 用到的时候去查询数据, 注意, 只有在用到的时候才会去查, 并且用一次查一次, 这种机制下, 就算将数据放到缓存中都没有用, 还是会用到一次查一次
//IQueryable<UserInfo> userInfoS = from u in dbContext.UserInfo
// where u.UserAddr.Contains("深")
// select u;
////只有在用到的时候才会去数据库查询数据
//foreach (var userInfo in userInfoS)
//{
// Console.WriteLine(userInfo.UserAddr+" "+userInfo.UserName);
//}
////var temp = from u in userInfoS
//// where u.Id > 1
//// select u;
//第二种延时加载的机制
IQueryable<UserInfo> userInfoS = from u in dbContext.UserInfo//.Include("OrderInfo")
//where u.UserAddr.Contains("深")
select u;
////假设当前用户表中有100个数据, 那么在此种嵌套循环下, 会和数据库交互101次, 所以就要使用from u in dbContext.UserInfo.Include("OrderInfo"), 表示在查询用户表的时候, 顺便把订单表查询出来, 这样的话, 就和数据库交互一次
IQueryable<UserInfo> userInfoS1 = from u in dbContext.UserInfo.Include("OrderInfo")
//where u.UserAddr.Contains("深")
select u;
foreach (var userInfo in userInfoS) //假设当前用户表中有100个数据, 那么在此种嵌套循环下, 会和数据库交互101次, 所以就要使用from u in dbContext.UserInfo.Include("OrderInfo"), 表示在查询用户表的时候, 顺便把订单表查询出来, 这样的话, 就和数据库交互一次
{
foreach (var orderInfo in userInfo.OrderInfo)
{
Console.WriteLine(orderInfo.BookAuth+" "+orderInfo.BookName);
}
}
//查询的时候, 什么时候使用include, 什么时候不用Include
//情景1: 用户表和订单表数据都是1亿条数据, 然后两个表进行连接查询的时候, 这个时候建议不要使用Include; 以此来解决大表的连接查询; 先对每个大表进行单独查询, 以此破解两个大表的联结查询
//数据量小的时候, 为了减少查询数据库的次数, 建议使用Include
//大数据表的查询优化:
//1. 把连接查询进行分解, 然后在内存组装数据; 先把数据从用户表中查询出来, 然后把数据从订单表中查询出来, 都放入内存中, 最后用程序在内存中进行组装
//2. 使用临时表; 常用于多表(超过2个以上)的大表进行组合查询的场景下, 注意, 当多个表连接的时候, 最好使用临时表, 临时表可以解决死锁问题; 注意临时表也会上锁, 但是临时表的锁, 只属于一个会话请求, 并且当此查询结束后, 此表即释放
#endregion
//把上面实体的变化保存到数据库中
dbContext.SaveChanges();
Console.WriteLine("保存成功");
Console.Read();
}
}
}
数据库
-- --------------------------------------------------
-- Entity Designer DDL Script for SQL Server 2005, 2008, 2012 and Azure
-- --------------------------------------------------
-- Date Created: 02/07/2017 22:52:32
-- Generated from EDMX file: C:\Users\LG\Desktop\ModelFirst\ModelFirst\Model1.edmx
-- --------------------------------------------------
SET QUOTED_IDENTIFIER OFF;
GO
USE [MyGroupDB];
GO
IF SCHEMA_ID(N'dbo') IS NULL EXECUTE(N'CREATE SCHEMA [dbo]');
GO
-- --------------------------------------------------
-- Dropping existing FOREIGN KEY constraints
-- --------------------------------------------------
-- --------------------------------------------------
-- Dropping existing tables
-- --------------------------------------------------
-- --------------------------------------------------
-- Creating all tables
-- --------------------------------------------------
-- Creating table 'UserInfo'
CREATE TABLE [dbo].[UserInfo] (
[Id] int IDENTITY(1,1) NOT NULL,
[UserName] nvarchar(32) NOT NULL,
[UserAddr] nvarchar(128) NULL
);
GO
-- Creating table 'OrderInfo'
CREATE TABLE [dbo].[OrderInfo] (
[Id] int IDENTITY(1,1) NOT NULL,
[BookName] nvarchar(max) NOT NULL,
[BookAuth] nvarchar(max) NOT NULL,
[UserInfo_Id] int NOT NULL
);
GO
-- --------------------------------------------------
-- Creating all PRIMARY KEY constraints
-- --------------------------------------------------
-- Creating primary key on [Id] in table 'UserInfo'
ALTER TABLE [dbo].[UserInfo]
ADD CONSTRAINT [PK_UserInfo]
PRIMARY KEY CLUSTERED ([Id] ASC);
GO
-- Creating primary key on [Id] in table 'OrderInfo'
ALTER TABLE [dbo].[OrderInfo]
ADD CONSTRAINT [PK_OrderInfo]
PRIMARY KEY CLUSTERED ([Id] ASC);
GO
-- --------------------------------------------------
-- Creating all FOREIGN KEY constraints
-- --------------------------------------------------
-- Creating foreign key on [UserInfo_Id] in table 'OrderInfo'
ALTER TABLE [dbo].[OrderInfo]
ADD CONSTRAINT [FK_R_UserInfo_OrderInfo]
FOREIGN KEY ([UserInfo_Id])
REFERENCES [dbo].[UserInfo]
([Id])
ON DELETE NO ACTION ON UPDATE NO ACTION;
GO
-- Creating non-clustered index for FOREIGN KEY 'FK_R_UserInfo_OrderInfo'
CREATE INDEX [IX_FK_R_UserInfo_OrderInfo]
ON [dbo].[OrderInfo]
([UserInfo_Id]);
GO
-- --------------------------------------------------
-- Script has ended
-- --------------------------------------------------
浙公网安备 33010602011771号