你真的了解EF吗?关于EntityFramework的高级优化

接上一篇文章。现在写程序,做项目不是说功能做完就完事了,在平常的开发过程中对于性能的考虑也是极其重要的。

关于ef的那些事,今天就来说说吧。首先必须得知道.net ef在程序中的五种状态变化过程与原理。

主要来说说查询部分的性能优化,在所有查询中,客户端查询出来的数据一般来说是不需要进行跟踪的。也就是说查询只是给用户看,不做其他任何操作。对于基于B/S模式的项目网站开发,应该是无状态的,也就是ef中的游离态(Unchanged)(个人理解)。如果是C/S可能还需要进行其他连接的状态。通俗的说,在开发过程不用去检测某一个属性或者类是否被修改或者删除。

例如:

AsNoTracking:它的作用就是在查询的过程中不被缓存,也就是不被保留,查出来就完事了,这样的状态就变成了Detached游离态

//AsNoTracking:它的性能比ToList快大约4.8倍,不被缓存的数据。
var item=db.Book.AsNoTracking().First(m=>m.Id==1);
Console.WriteLine(db.Entry(item).State); //输出Detached(游离态)

去掉AsNoTracking

var item=db.Book.First(m=>m.Id==1);
Console.WriteLine(db.Entry(item).State); //输出UnChanged(持久态)

也就是加上AsNoTracking做出来的查询操作,就和数据库断绝了关系(个人理解)这样对性能也是一个极好的优化。

然后来说说在项目中对ef整体框架优化的使用。

C#是一门面向对象的语言无外乎就是封装、继承、多态。。。类可以继承类,同样接口也可以继承接口。面向对象的思想就是每张表都应该有一个父类,只写一遍,其他类继承就好了不用重复去写。

建立一个空白的解决方案,添加一个名为BaseEntity的类,你可以把它看做是所有类的基础类(父类)。

重点来说说这个BaseEntity为什么要作为基础类,它的用意何在。

先看看里面的写了些什么吧!

以前用int或者long作为主键自增长的数据类型,这样后期数据非常庞大的时候可能会无法预估难免可能会出现重复的数据,这个时候对于整个系统来说就无法保障了。

Guid给我做出了一个计算,它是32位的数字加字母的组合,而且是特别长的不会重复的自增数,可以这样去理解。

DateTime就是每条数据的创建时间,IsRemove就是作为数据逻辑删除的标识,也就是说,每个类(表)都会存在这三个字段属性。你可以通过DateTime对没张表进行排序的操作。

using System;
namespace Book.Models
{
    public class BaseEntity
    {
        public Guid Id { get; set; }=Guid.NewGuid(); //计算32位,字母加数字,特别长的,不重复的,自增数
        public DateTime DateTime { get; set; }=DateTime.Now;    //每条数据的创建时间
        public bool IsRemove { get; set; }  //伪删除的标识
    }
}

创建BookType类

using System.ComponentModel.DataAnnotations;

namespace Book.Models
{
    public class BookType:BaseEntity
    {
        [StringLength(20)]
        public string Name { get; set; }
    }
}

创建Book类

using System.ComponentModel.DataAnnotations;

namespace Book.Models
{
    public class Book:BaseEntity
    {
        [StringLength(50),Required]
        public string Name { get; set; }
        public decimal Price { get; set; }
    }
}

这两个类都会继承BaseEntity

在App.Config里面写上你自己的数据库连接字符串

这样的目的就是去生成数据库,只做生成数据库的操作。这里只是在Models层写了一次,在后期加上表示层还有在写一遍!

接下来就是去通过指令迁移到数据库,操作有三步:

  1. 启动迁移:enable-migrations
  2. 添加迁移:add-migration ‘参数’
  3. 更新数据库:update-database(如果你需要添加或者修改某个字段属性,只需要进行第二步和第三步的操作即可!)

记住默认项目要选择你的Models,如果是多个项目(我这里是只有一个)就必须要把Models设为启动项目,不然迁移指令可能不会起到作用