EF Core

搭建EF Core开发环境

EF Core是对于底层ADO.NET Core封装

1.建立实体类

     

  建立Book.cs类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCore_demo
{
    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; }//作者名字
    }
}

建立Person.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCore_demo
{
    public class Person 
    { 
    public long Id { get; set; }//主键
    public string Name { get; set; }
    public int Age { get; set; }
    }
}

 PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer

EF Core_第1张图片

2.建立配置类Config

        创建实现了IEntityTypeConfiguration接口的实体配置类,配置实体类和数据表的对应关系(这里约定大于配置)

        创建BookConfig.cs

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCore_demo
{
    class BookConfig : IEntityTypeConfiguration
    {
        public void Configure(EntityTypeBuilder builder)
        {
            builder.ToTable("T_Books");
        }
    }
    
}

 创建PersonConfig

        

using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCore_demo
{
    class PersonConfig : IEntityTypeConfiguration
    {
        public void Configure(EntityTypeBuilder builder)
        {
            builder.ToTable("T_Persons");
        }
    }
}

3.建立DbContext

        创建继承DbContext的类

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCore_demo
{
    class MyDbContext : DbContext
    {
        public DbSet Books { get; set; }
        public DbSet Persons { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            string connStr = "Server=SHA-CLPS-D36;Database=Csharp_demo;Trusted_Connection=True;Encrypt=True;TrustServerCertificate=True";
            //string connStr = "Data Source = SHA-CLPS-D36; Initial Catelog= Csharp_demo; Integrate Security= true";
            optionsBuilder.UseSqlServer(connStr);

        }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
        }
    }
}

        Onconfiguration说明连接哪一个数据库

        OnModeCreating从哪里加载IentityConfiguration

这里我遇到一个报错问题(已解决)

Error Number:-2146893019,State:0,Class:20
A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 - The certificate chain was issued by an authority that is not trusted.)

 

解决方法:

在登录时,更改选项的连接属性,解决方案、信任服务器证书选项都选择或者都不选择,不能只选一个

连接字符串里的设置是:Encrypt=True;TrustServerCertificate=True

4.生成数据库

        Migration(迁移)工具生成数据库,在面对对象的ORM开发中。根据对象的定义变化,自动更新数据库中的表以及表结构的操作.

        为了使用生成数据库工具,Nuget安装Microsoft.EntityworkCore.Tools先

Install-Package Microsoft.EntityFrameworkCore.Tools

        然后执行Add-Migration命令

 Add-Migration InitialCreate

 代码需要执行后才会应用对数据库的操作

Update-database

每更新一次,都是一个新的Migration文件,所以每次都需要给他一个名字-合法变量名,有意义

Add-Migration ***

 连接成功,并成功创建表

EF Core_第2张图片

        修改已创建好的表结构(实体中修改,新增,删除表,列等) 

(1)新增一个实体

为了这个实体能和数据库产生关系,一定要在MyDbContext里面声明

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCore_demo
{
    public class Dog
    {
        public long Id { get; set; }//主键
        public string Name { get; set; }
    }
}

 EF Core_第3张图片

(2).新增属性

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCore_demo
{
    public class Person 
    { 
    public long Id { get; set; }//主键
    public string Name { get; set; }
    public int Age { get; set; }
    
    public string BirthPlace { get; set; }//新增出生地
    
    public double? Salary { get; set; }//加个?表示可空的salary
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCore_demo
{
    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)修改列的属性

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFCore_demo
{
    class BookConfig : IEntityTypeConfiguration
    {
        public void Configure(EntityTypeBuilder builder)
        {
            builder.ToTable("T_Books");
            builder.Property(b=>b.Title).IsRequired().HasMaxLength(50);
            builder.Property(b => b.AuthorName).IsRequired().HasMaxLength(50);

        }
    }
    
}

 所有修改结束记得重新Add-Migration ***,再Update-database

5.EF Core数据的增删改查

(1)插入数据

首先new一个DbContext对象,避免资源泄漏,需要using一下。

调用Add()方法,然后SaveChanges()才真正加入。

ctx有异步方法,我们需要养成用异步方法的好习惯,后面我们都是用异步方法。

using System;

namespace EFCore_demo // Note: actual namespace depends on the project name.
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            //crx=逻辑上的数据库
            using(MyDbContext ctx=new MyDbContext())
            {
                Dog d=new Dog();
                d.Name = "wangcai";
                ctx.Add(d);//把d对象加入Dogs这个逻辑上的表里面
                            //ctx.SvaceChanges();//Update-Database

                Book b= new Book();
                b.AuthorName = "rachel";
                b.Price = 18;
                b.PubTime=DateTime.Now;
                b.Title= "C language";
                ctx.Add(b);

                await ctx.SaveChangesAsync();
            }
        }
    }
}

(2)查询数据(请事先将表中插入一些数据以便查询)

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

using System;
using System.Linq;

namespace EFCore_demo // Note: actual namespace depends on the project name.
{
    public class Program
    {
        static async Task Main(string[] args)
        {
            //crx=逻辑上的数据库
            using (MyDbContext ctx = new MyDbContext())
            {
                //select * from xxx from price>80
                //var books= ctx.Books.Where(b=>b.Price>10);
                
                var books = ctx.Books.Where(b => b.Price > 0);
                foreach (var b in books)
                {
                    Console.WriteLine(b.Title);
                }
                //查询不需要SaveChangeAsync();
                //await ctx.SaveChangesAsync();
            }
        }
    }
}

(3) 删除数据

        删除也是先把要修改的数据查询出来,然后再调用Dbset或者DbContext的Remove方法把对象删除,然后再执行SaveChangeAsync()保存修改。

using System;
using System.Linq;

namespace EFCore_demo // Note: actual namespace depends on the project name.
{
    public class Program
    {
        static async Task Main(string[] args)
        {
            //crx=逻辑上的数据库
            using (MyDbContext ctx = new MyDbContext())
            {
                
                var b = ctx.Books.Single(b => b.Id == 2);
                b.Title = "java is best language";
                await ctx.SaveChangesAsync();
            }
        }
    }
}

(4)更新数据

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

using System;
using System.Linq;

namespace EFCore_demo // Note: actual namespace depends on the project name.
{
    public class Program
    {
        static async Task Main(string[] args)
        {
            //crx=逻辑上的数据库
            using (MyDbContext ctx = new MyDbContext())
            {
                //select * from xxx from price>80
                //var books= ctx.Books.Where(b=>b.Price>10);
                
                var b = ctx.Books.Single(b => b.Title == "SQL");
                ctx.Remove(b);//也可以写成ctx.Books.Remove(b);
                await ctx.SaveChangesAsync();
            }
        }
    }
}

6.实体的配置

 约定配置:

  主要规则:

  •  表名采用DbContext中的对应的DbSet的属性名。
  •  数据表列的名字采用实体类属性的名字,列的数据类型采用和实体类属性类型最兼容的类型。
  •  数据表列的可空性取决于对应实体类属性的可控性。
  •  名字为Id的属性为主键,如果主键为Guid类型,则默认采用默认的Guid生成机制生成主键值。

两种配置方式

(1)DataAnnotation

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

[table("T_Books")]
public class Book
{

}

优点:简单。缺点:耦合

(2)Fluent API

builder.ToTable("T_Books");

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

缺点:复杂。优点:解耦

7.编写调用EFCore的业务代码

你可能感兴趣的:(.Net,数据库,c#,开发语言)