EntityFramework数据持久化复习资料5、LINQ概述与应用(超终点)

简介: EntityFramework数据持久化复习资料5、LINQ概述与应用(超终点)

EntityFramework数据持久化复习资料5、LINQ概述与应用(超终点)


前言

微软官方提供的ORM工具,ORM让开发人员节省数据库访问的代码时间,将更多的时间放到业务逻辑层代码上。开发人员使用Linq语言,对数据库操作如同操作Object对象

一样省事。EF有三种使用场景,1. 从数据库生成Class,2.由实体类生成数据库表结构,3.通过数据库可视化设计器设计数据库,同时生成实体类。

ORM (对象关系型映射)是将数据存储从域对象自动映射到关系型数据库的工具。ORM主要包括3个部分:域对象、关系数据库对象、映射关系。ORM使类提供自动化CRUD,使

开发人员从数据库API和SQL中解放出来。以前是使用ADO.NET来进行对数据库中得数据表进行操作,现在,使用ORM直接对对象进行操作,操作对象就等于操作数据库表,

那怎么让对象和数据库表一一对应起来?这个过程就是通过ORM框架来完成的,操作对象就是操作数据库也是通过ORM来完成的。ORM框架就是做对象和数据库的映射的。

那么EntityFramework的作用是什么?

我的理解就是大大简化数据库操作的,举个例子:在没有使用EF前,我们要编写复杂的SQL语句,而使用了EF之后,将会减少编写复杂的SQL语句过程。

开发环境

系统环境:win7及以上,本示例环境win11

开发工具:Visual Studio 2017及以上

创建项目:

       控制台请创建【控制台应用(.NET Framework)】

       Web请创建【ASP.NET Web应用程序(.NET Framework)】

数据库:SQLServer数据库2012及以上版本·如果下载最新版本,使用免费版本即可。

       本地数据库链接:【.】或【127.0.0.1】

       登陆方式1:【本地登陆】

       登陆方式2:账号【sa】 pwd【admin】

       测试数据库名称:【mytest】

       排序规则:【Chinese_PRC_CI_AS】


LINQ的概述

LINQ(Language Integrated Query,语言集成查询)提供了一种跨数据源和数据格式的统一模型,实现查询。

在LINQ中,可以使用与查询数据库相同的编码模式来查询和转换XML文档、SQL数据库、ADO.NET数据集以及.NET集合中的数据,并支持LINQ查询的任何格式的数据。

LINQ关键字

关键字

说明

from

指定范围变量和数据源

where

根据bool表达式从数据源中筛选数据

select

指定查询结果中的元素所具有的类型或表现形式

group

对查询结果按照键/值执行分组

into

提供一个标识符,它可以充当对join、group或select子句结果的引用

orderby

对查询出的元素执行排序(ascending/descending)

join

按照两个指定匹配条件对等连接两个数据源

let

产生一个用于存储子表达式查询结果的范围变量

LINQ语法

只有实现了【IEnumerable】接口的数据源,才能执行相关的LINQ操作。

from [type] id in source

[join [type] id in source on expr equals expr [into subGroup]]

[from [type] id in source | let id = expr | where condition]

[orderby ordering,ordering,ordering...]

select expr | group expr by key

[into id query]

基础示例

这里我写了一个基础的示例,这个示例返回的是nums数组中所有的偶数。

这个里这个数据集可以使用【数组】/【列表】都可以。

int[] nums = { 123, 42, 13, 5, 346, 45, 23423, 63, 4, 2, 433, 243, 24, 7 };
// 2.创建查询.
var LINQ =
//from开始 num是每个nums返回的对象,in是固定语法,在的意思
from num in nums
//where是筛选,筛选的方式是要偶数
where (num % 2) == 0
//每次返回num结果
select num;
//输出测试
foreach (var item in LINQ)
{
    Console.WriteLine(item);
}

实际效果:

对象筛选示例

示例类【Users】

创建对象列表

数据初始化函数init()

private static List<Users> init()
{
    List<Users> list = new List<Users>();
    list.Add(new Users() {id=1,userName="王语嫣",age=15 });
    list.Add(new Users() {id=2,userName="龙姑娘",age=18 });
    list.Add(new Users() {id=3,userName="小龙女",age=16 });
    list.Add(new Users() {id=4,userName="赵灵儿",age=17 });
    list.Add(new Users() {id=5,userName="王语嫣",age=22 });
    return list;
}

1、LINQ根据id精准查询·返回单个对象

这里我们是单个的id匹配,我们最后需要使用【SingleOrDefault】。

List<Users> list = init();
var linq = (from item in list
            where item.id == 2
            select item).SingleOrDefault();
Console.WriteLine(linq.id);
Console.WriteLine(linq.userName);
Console.WriteLine(linq.age);

异常效:1:(这里我查询的是20,很明显没有这个ID,故而报了异常)

异常效果2:(数据格式化了一下,我把其中id=2的值写了2个。使用SingleOrDefault查询出两个相同的结果依然会出现异常提示)

一般情況下都会使用【SingleOrDefault】,因为这能直接判断这个唯一的信息是否正确,项目中出现相同的值肯定是有异常的,就可以帮助我们定位异常。

2、LINQ根据【昵称】模糊查询返回列表

模糊查询并遍历·这里用到的是字符串的【Contains】函数,ToList()返回一个列表。

List<Users> list = init();
var linq=(from item in list
          where item.userName.Contains("龙")
          select item).ToList();
foreach (var item in linq)
{
    Console.WriteLine(item.id);
    Console.WriteLine(item.userName);
    Console.WriteLine(item.age);
}

实际效果:

3、LINQ分组查询·返回列表

我们把聂小倩和龙姑娘都改成18岁,我们根据年龄进行分组。

private static List<Users> init()
{
    List<Users> list = new List<Users>();
    list.Add(new Users() { id = 1, userName = "王语嫣", age = 15 });
    list.Add(new Users() { id = 2, userName = "龙姑娘", age = 18 });
    list.Add(new Users() { id = 3, userName = "小龙女", age = 16 });
    list.Add(new Users() { id = 4, userName = "赵灵儿", age = 17 });
    list.Add(new Users() { id = 5, userName = "聂小倩", age = 18 });
    return list;
}

基础分组示例代码:

List<Users> list = init();
var linq = (from item in list
            group item by item.age
            ).ToList();
Console.WriteLine(linq.Count);

分组效果:

分组示例代码:

List<Users> list = init();
var linq = from item in list
                //分组后将数据放置到p中
            group item by item.age into p
            //根据p重新创建一个匿名对象返回数据
            select new { p.Key, KeyCount = p.Count() };
foreach (var item in linq)
{
    Console.WriteLine(item);
}

遍历效果:

4、LINQ排序·返回列表

这里的关键字是orderby,正序是【ascending】倒序是【descending】。

List<Users> list = init();
var linq = from item in list
           orderby item.age descending
           select item;
foreach (var item in linq)
{
    Console.WriteLine(item.id);
    Console.WriteLine(item.userName);
    Console.WriteLine("倒序年龄:"+item.age);
}

倒序输出效果:

5、聚合查询

聚合查询共计有5个,但是如果数量较大的计数就需要使用LongCount故而有6个属性

方法名

说明

Count

对集合中的元素计数,以及对集合中满足条件的元素计数

LongCount

与Count相同,当Count中元索的个数超过int类型值的上限时使用

Max

确定集合中的最大值

Min

确定集合中的最小值

Sum

计算集合中值的总和

Average

计算集合中值的平均值

List<Users> list = init();
//聚合函数
//Count与longCount
int count = (from item in list
             where item.age > 15
             select item).Count();
Console.WriteLine("大于15岁的数量:"+count);
//max
int max = list.Max(o=>o.age);
Console.WriteLine("最大年龄:"+max);
//min
int min = list.Min(o => o.age);
Console.WriteLine("最小年龄:" + min);
//sum
int sum = list.Sum(o => o.age);
Console.WriteLine("年龄总数:"+sum);
//average
double avg = list.Average(o => o.age);
Console.WriteLine("平均年龄:"+avg);

输出效果:

6、多表联合查询

重新创建一个UsersDetalis对象,用作多表联合查询示例。

Users列表函数

/// <summary>
/// 用户基础信息初始化
/// </summary>
/// <returns></returns>
private static List<Users> initUsers()
{
    List<Users> list = new List<Users>();
    list.Add(new Users() { id = 1, userName = "王语嫣", age = 15 });
    list.Add(new Users() { id = 2, userName = "龙姑娘", age = 18 });
    list.Add(new Users() { id = 3, userName = "小龙女", age = 16 });
    list.Add(new Users() { id = 4, userName = "赵灵儿", age = 17 });
    list.Add(new Users() { id = 5, userName = "聂小倩", age = 18 });
    return list;
}

UsersDetalis列表函数

/// <summary>
/// 用户详情
/// </summary>
/// <returns></returns>
private static List<UserDetails> initUserDetails() {
    List<UserDetails> list = new List<UserDetails>();
    list.Add(new UserDetails() {id=1,uid=1,introduce="琅嬛福地,超级学霸。" });
    list.Add(new UserDetails() {id=2,uid=3,introduce="活死人墓,冰山美人。" });
    list.Add(new UserDetails() {id=3,uid=4,introduce="灵蛇岛,等着逍遥哥哥。" });
    list.Add(new UserDetails() {id=4,uid=5,introduce="聂小倩就是王祖贤" });
    return list;
}

7、多表联合查询基础示例

使用的关键字是【join】进行链接,匹配id处理笛卡尔积的时候必须使用【equals】做判断。

链接步骤:

1、form第一个列表

2、通过【join】链接另外一个列表

3、通过【on】去掉笛卡尔积

4、筛选、排序、分组操作

5、重新组合匿名对象

//用户表
var list = initUsers();
//用户详情表
var list_details = initUserDetails();
//多表联合查询
var newList =
    from users in list
    join usersDetails in list_details
    on users.id equals usersDetails.uid
    select new
    {
        users_id = users.id,
        userName = users.userName,
        age = users.age,
        users_details_id = usersDetails.id,
        introduce = usersDetails.introduce
    };
foreach (var item in newList)
{
    Console.WriteLine(item.users_id);
    Console.WriteLine(item.userName);
    Console.WriteLine(item.age);
    Console.WriteLine(item.users_details_id);
    Console.WriteLine(item.introduce);
    Console.WriteLine("-------------------");
}

实际效果:其中id=2的用户龙姑娘在详情表中并没有显示,故而数据中不显示。

8、多表联合查询——模糊查询

where users.userName.Contains("龙")

//用户表
var list = initUsers();
//用户详情表
var list_details = initUserDetails();
//多表联合查询
var newList =
    from users in list
    join usersDetails in list_details
    on users.id equals usersDetails.uid
    where users.userName.Contains("龙")
    select new
    {
        users_id = users.id,
        userName = users.userName,
        age = users.age,
        users_details_id = usersDetails.id,
        introduce = usersDetails.introduce
    };
foreach (var item in newList)
{
    Console.WriteLine(item.users_id);
    Console.WriteLine(item.userName);
    Console.WriteLine(item.age);
    Console.WriteLine(item.users_details_id);
    Console.WriteLine(item.introduce);
    Console.WriteLine("-------------------");
}

查询效果:因为只有1个符合,所以正确。

9、多表查询·排序

倒序

orderby users.age descending

正序

orderby users.age ascending

//用户表
var list = initUsers();
//用户详情表
var list_details = initUserDetails();
//多表联合查询
var newList =
    from users in list
    join usersDetails in list_details
    on users.id equals usersDetails.uid
    orderby users.age descending
    select new
    {
        users_id = users.id,
        userName = users.userName,
        age = users.age,
        users_details_id = usersDetails.id,
        introduce = usersDetails.introduce
    };
foreach (var item in newList)
{
    Console.WriteLine(item.users_id);
    Console.WriteLine(item.userName);
    Console.WriteLine(item.age);
    Console.WriteLine(item.users_details_id);
    Console.WriteLine(item.introduce);
    Console.WriteLine("-------------------");
}

排序效果:

10、分页查询

  1. Skip代表从第几条开始查询
  2. Take代表每页查询几条
//用户表
var list = initUsers();
//用户详情表
var list_details = initUserDetails();
//多表联合查询·分页
var newList = (from users in list
               join usersDetails in list_details
               on users.id equals usersDetails.uid
               select new
               {
                   users_id = users.id,
                   userName = users.userName,
                   age = users.age,
                   users_details_id = usersDetails.id,
                   introduce = usersDetails.introduce
               }).Skip(0).Take(2);

相关文章
|
6月前
|
SQL 存储 开发框架
EntityFramework数据持久化复习资料4、Lambda表达式的使用(重点内容)
EntityFramework数据持久化复习资料4、Lambda表达式的使用(重点内容)
53 0
|
6月前
|
SQL 存储 开发框架
EntityFramework数据持久化复习资料1、委托
EntityFramework数据持久化复习资料1、委托
59 0
|
6月前
|
SQL 存储 开发框架
EntityFramework数据持久化复习资料6、EntityFramework引入
EntityFramework数据持久化复习资料6、EntityFramework引入
47 0
|
数据库 索引 缓存