.NET Core EF Core

.NET Core EF Core

一.什么是ORM

1.ORM:Object Relation Mapping. 让开发者用对象操作的形式操作关系数据库.

比如插入:

User user = new User(){Name="admin",Password="123"};
orm.Save(User);

比如查询:

Book b = orm.Book.Single(b=>b.Id==3||b.Name.Contains(".NET"));
string bookName = b.Name;
string aName = a.Author.Name;
2.有哪些ORM:EF core,Dapper,SQLSugar,FreeSql

二.EF Core与其他ORM比较

1.Entity Framework Core(EF Core)是微软的ORM框架

优点:功能强大,官方支持,生产效率高,力求屏蔽底层数据库差异;

缺点:复杂,上手门槛高,不熟悉EFCore的话可能会进坑

2.Dapper

优点:简单,N分钟即可上手,行为可预期性强

缺点:生产效率低,需要处理

3.EF Core是模型驱动(Model-Driven)的开发思想,Dapper是数据库驱动(DataBase-Driven)的开发思想的,没有优劣,只有比较
4.性能:Dapper等 不等于 性能高;EF Core 不等于 性能差
5.EF Core是官方推荐,推进的框架,尽量屏蔽底层数据库差异,.NET开发者必须熟悉,根据的项目情况再决定用哪个

三.EF Core用什么数据库

1.EF Core是对于底层ADO.NET Core的封装,因此ADO.NET Core支持的数据库不一定被EF Core支持.

2.EF Core支持所有主流的数据库,包括MS SQL Server,Oracle,MySQL,PostgreSQL,SQLite等.可以自己实现Provider支持其他数据库.

3.对于SQLServer支持最完美,MySQL,PostgreSQL也不错

四.开发环境搭建

1.经典步骤:

建实体类;

建DbContext;

生成数据库;

编写调用EF Core的业务代码

2.Book.cs

public class Book
{
    public long Id { get; set; }//主键
    public string Title  { get; set; }//标题
    public DateTime PubTime { get; set; }//发布日期
    public double Price { get; set; }   //单价
}

3.Install-Package Microsoft.EntityFrameworkCore.SqlServer

4.创建实现了IEntityTypeConfiguration接口的实体配置类,配置实体类的数据表的对应关系 BookConfig.cs

class BookConfig : IEntityTypeConfiguration<Book>
{
    public void Configure(EntityTypeBuilder<Book> builder)
    {
        builder.ToTable("T_Books");
    }
}

5.创建继承自DbContext的类

class MyDbContext : DbContext
{
    public DbSet<Book> Books { get; set; }
    public DbSet<Person> Persons { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        base.OnConfiguring(optionsBuilder);
        optionsBuilder.UseSqlServer("");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        //从当前程序集加载所有的IEntityTypeConfiguration
        modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
    }

2.Migration

概念:Migration数据路迁移

面向对象的ORM开发中,数据库不是程序员手动创建的,而是由Migration工具生成的.关系数据库只是盛放模型数据的一个媒介而已,理想状态下,程序员不用关系数据库的操作.

根据对象的定义变化,自动更新数据库中的表以及表结构,叫做Migration(迁移).

迁移可以分为多步(项目进化),也可以回滚.

1.安装Migration
Install-Package Microsoft.EntityFrameworkCore.Tools

再在"程序包管理控制台"中执行如下命令

Add-Migration InitialCreate

会自动在项目的Migration文件夹中中生成操作数据库的C#代码.讲解一下生成代码的作用

InitialCreate是什么?

2.代码需要执行后才会应用对数据库的操作,"程序包管理器控制台"中执行

Update-database

3.查看一下数据库,表就建好了

3.修改表结构

1.项目开发中,根据需要,可能会在已有实体中修改,新增,删除表列等

2.想要限制Title的最大长度为50,Title字段设置为"不可为空",并且想增加一个不可为空且最大长度为20的AuthorName(作者名字)属性

首先在Book实体类中增加一个AuthorName属性

public class Book
{
    public long Id { get; set; }//主键
    public string Title  { get; set; }//标题
    public DateTime PubTime { get; set; }//发布日期
    public double Price { get; set; }   //单价
    public string AuthorName { get; set; }//作者名字
}

3.修改BookEntityConfig

public void Configure(EntityTypeBuilder<Book> builder)
{
    builder.ToTable("T_Books");
    builder.Property(b => b.Title).HasMaxLength(50).IsRequired();
    builder.Property(b => b.AuthorName).HasMaxLength(20).IsRequired();
}

4.插入数据

1.只要操作Books属性,就可以向数据库中增加数据,但是通过C#代码修改Books中的数据只是修改了内存中的数据.

对Books修改后,现需要调用DbContext的异步方法==SaveChangeAsync()==把修改保存到数据库.也有同步的保存方法SaveChanges(),但是用EF Core都推荐用异步方法.

2.EF Core默认会跟踪(Track)实体类对象以及DbSet的改变.

3.演示数据插入

static async Task Main(string[] args)
{
    //ctx=逻辑上的数据库
    using (MyDbContext ctx = new MyDbContext())
    {
        Dog d = new Dog();
        d.Name = "Trump";
        ctx.Dogs.Add(d);//把d对象加入Dogs这个逻辑上的表里面
        await ctx.SaveChangesAsync();
    }
}

5.查询数据

1.DbSet实现了IEnumerable接口,因此可以对DbSet实施Linq操作来进行数据查询,EF Core会把Linq操作转换为SQL语句,面向对象,而不是面向数据库(SQL).

IQueryable books = ctx.Books.Where(b => b.Price > 80);

2.可以使用OrderBy操作进行数据的排序

var booksPrice = ctx.Books.OrderBy(b => b.Price).Where(b=>b.Price<10);
foreach (var book in booksPrice)
{
    Console.WriteLine(book.Title +"======"+book.Price);
}

6.修改,删除

1.要对数据进行修改,首先需要把修改的数据查询出来,然后再对查询出来的对象进行修改,然后再执行SaveChangesAsync()保存修改

var b = ctx.Books.Single(b => b.Title == “算法”);
b.AuthorName = “xiaomimi”;

2.删除也是先把要修改的数据查询出来,然后再调用DbSet或者DbContext的Remove方法把对象删除,然后再执行

SaveChangeAsync()保存修改.

var d = ctx.Dogs.Where(b => b.Id > 3);
ctx.Dogs.RemoveRange(d);

await ctx.SaveChangesAsync();

7.批量修改,删除

1.目前批量修改,删除多条数据的方法

局限性:性能低:查出来,再一条条Update,Delete,而不能执行Update…where;delete…Where;

2.官方目前还没有支持高效的批量Update,Delete,有在后续版本中增加

8.约定配置

主要规则:

1.表名采用DbContext中的对应的DbSet的属性名

2.数据表列的名字采用实体类属性的名字,列的数据类型采用和实体类属性类型最兼容的类型

3.数据列表的可空性取决于对应实体类属性的可空性.

4.名字为Id的属性为主键,如果主键为short,int或者long类型,则默认采用自增字段,如果主键为Guid类型,则默认采用默认的Guid生成机制生成主键值

1.两种配置方式
1.Data Annotation

把配置以特性(Annotation)的形式标注在实体类中

[Table("T_Books")]
public class Book
{    
}

优点:简单

缺点:耦合

[Table("T_Cats")]
class Cats
{
    public long Id { get; set; }
    [Required]
    [MaxLength(22)]
    public string Name { get; set; }
}
2.Fluent API
builder.ToTable("T_Books");

把配置写到单独的配置类中

缺点:复杂

优点:解耦

1.视图与实体类的映射:

modelBuilder.Entity().ToView(“blogsView”);

2.排除属性映射

moderBuilder.Entity().Ignore(b=>b.Name2);

3.配置列名:

modelBuilder.Entity.Property(b=>b.BlogId).HasColumnName(“blog_id”);

4.配置列数据类型

builder.Property(e=>e.Title).HasColumnType(“varchar(200)”)

5.配置主键

默认吧名字为Id或者"实体类型+Id"的属性作为主键,可以用HasKey()来配置其他属性作为主键

modelBuilder.Entity().HasKey(c=>c.Number);

支持符合主键,但是不建议使用

6.生成列的值

modelBuilder.Entity().Property(b=>b.Number).ValueGeneratedOnAdd();

7.可以用HasDefaultValue()为属性设定的默认值

modelBuilder.Entity().Property(b=>b.Age).HasDefaultValue(6);

8.索引

modelBuilder.Entity().HasIndex(b=> b.Url);

复合索引

modelBuilder.Entity().HasIndex(p=>new{p.FirstName,p.LastName});

唯一索引:IsUnique();

聚集索引:IsClustered()

9… 用EF Core太多高级特性的时候谨慎,尽量不要和业务逻辑混合在一起,以免"不能自拔"

比如Ignore,Shadow,Table Splitting等…

3.大部分功能重叠,可以混用,但是不建议混用
2.选择

1.Data Annotation,Fluent API大部分功能重叠,可以混用,但是不建议混用

2.有人建议混用,即用了Data Annotation的简单,有用到Fluent API的强大,而且实体类上标注的[MaxLength(50)],[Required]等标注可以被ASP.NET Core中的验证框架等复用

9.自增主键

1.EF Core支持多种主键生成策略:自动正常,Guid;Hi/Lo算法等

2.自动增长.

优点:简单;

缺点:数据库迁移以及分布式系统中比较麻烦;并发性能差.long,int等类型主键,默认是自增.因为是数据库生成的值,所以SaveChanges后会自动把主键的值更新到Id属性

3.自增字段的代码中不能为Id赋值,必须保持默认值0,否则运行的时候就会报错.

10.Guid主键

1.Guid算法(或UUID算法)生成一个全局唯一的Id.适合于分布式系统,在进行多数据库数据合并的时候很简单.

优点:简单 高并发 全局唯一

缺点:磁盘空间占用很大

2.Guid值不连续,使用Guid类型做主键的时候,不能把主键设置为聚集索引,因为聚集索引时按照顺序保存主键的,因此用Guid做主键性能较差.

比如MySQL的InnoDb引擎中主键是强制使用聚集索引的.有的数据库支持部分连续Guid,比如SQL Server中的NewSequentialId(),但也不能解决问题.在SQL Server等中,不要把Guid主键设置为聚集索引;在MySQL中,插入频繁的表不要用Guid做主键

3.演示Guid用法

既可以让EF Core给赋值,也可以手动赋值

11.其他主键方案

1.混合自增的Guid(非复合主键).用自增列做物理的主键,而用Guid列做逻辑上的主键.把自增列设置为表的主键,而在业务上查询数据时候把Guid当主键用.在和其他表关联以及和外部系统通讯的时候(比如前端显示数据的标识的时候)都是使用Guid列.不进保证了性能,而且利用了Guid的有点,而且减轻了自增主键导致主键值可被预测带来的安全性问题

2.Hi/Lo算法:EF Core支持Hi/Lo算法来优化自增列,主键值由两部分组成:高位(Hi)和低位(Lo),高位由数据库生成,两个高位之间间隔若干个值,由程序在本地生成低位,低位的值在本地自增生成.不同进程或者集中不同服务器获取的Hi值不会重复,而本地进程计算的Lo则可以保证在本地高效率的生成主键值,但是HiLo算法不是EF Core的标准

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值