.Net开发——EFCore

2 篇文章 0 订阅

1 EFCore是一个ORM框架

EFCore(EntityFramworkCore)是对底层ADO.NET.Core重新封装的一个数据操作框架,因此ADO.NET.Core支持的多种数据库都可以被EFCore支持。

EF Core 可用作对象关系映射程序 (O/RM),这可以实现以下两点:

  • 使 .NET 开发人员能够使用 .NET 对象处理数据库
  • 避免SQL的编写。
  • 开发更加高效

2 EFCore模型配置

EFCore的主要核心逻辑就是操作对象来处理数据库中的增删改查,因此.Net对象就需要对应着数据库中的实体表。因此要进行实体对象与数据库表的模型配置。
模型配置的方式有两种,基于特性与Fluent API


基于特性配置

    /// <summary>
    /// 使用Data_Annotation来进行模型映射
    /// Table特性,指明表名
    /// MaxLength,设定属性的最大长度,对应数据库即字段的最大长度
    /// Required,属性不为空,意即数据库中该字段不可为空
    /// </summary>
    [Table("T_CAT")]
    public class Cats
    {
        [Key]
        [MaxLength(30)]
        public string Id { get; set; }
        [MaxLength(30)]
        [Required]
        public string Name { get; set; }
    }

基于FluentAPI 配置
1 创建模型类

    public class LabelConfig
    {
        public string ROW_ID { get; set; }
        public string SYSTEM_NAME { get; set; }
        public string SYSTEM_GROUP { get; set; }
        public string LABEL_NAME { get; set; }
        public string LABEL_LAN { get; set; }
        public string LABEL_DESC { get; set; }
        public string CREATE_EMP { get; set; }
        public DateTime? CREATE_TIME { get; set; }
        public string AGE1 { get; set; }
        public string AGE2 { get; set; }
    }

2 创建映射配置类

    public class SignAgentConfig : IEntityTypeConfiguration<LabelConfig>
    {
        public void Configure(EntityTypeBuilder<LabelConfig> builder)
        {
            //TEntity与表C_SIGN_AGENT的映射关系
            //未具体设置字段间的映射关系时,默认对象的属性和表的字段一一对应
            builder.ToTable("REPLACE_LABEL_CONFIG");
            //设置字段 
            builder.Property(i => i.ROW_ID).HasMaxLength(30).IsRequired();
            //忽略Age2的映射
            builder.Ignore(i=>i.AGE2);
            //设置主键
            builder.HasKey(i=>i.ROW_ID);
            //设置列名映射
            builder.Property(i => i.AGE1).HasColumnType("VARCHAR2(20)").HasColumnName("AGE");
            //设置默认值
            builder.Property(i => i.SYSTEM_GROUP).HasDefaultValue("defaltGroup");
            //设置索引 IsUnique唯一索引
            builder.HasIndex(i=>i.LABEL_NAME).IsUnique().HasName("Index1");
            //设置复合索引
            //IndexBuilder HasIndex([NotNullAttribute] Expression<Func<TEntity, object>> indexExpression)
            //Expression<Func<TEntity, object>> indexExpression 
            builder.HasIndex(i => new
            {
                i.LABEL_NAME,
                i.LABEL_LAN
                //设置索引名称 HasName
            }).HasName("Index2");
        }
    }

4 DbContext配置

    /// <summary>
    /// DbContext 类比与整个数据库中session连接,可在单次连接中操作DbSet<T>来操作数据库,如查找,
    /// DbSet<TEntity> 类比与数据库中的单个表;当增加、移除表时,需要同时增加、移除DbSet<TEntity>属性
    /// </summary>
    public class MyDbContext:DbContext
    {
        public DbSet<LabelConfig> agents { get; set; }
        public DbSet<Cats> cats { get; set; }

        //配置数据库连接字符信息
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            string connection_str = "连接字符串";
            //使用Oracle数据库
            optionsBuilder.UseOracle(connection_str);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            //模型加载,加载当前Assembly程序集中继承了IEntityTypeConfiguration<T>的模型配置类
            modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
        
        }
    }

3 数据迁移Migration

根据实体类定义的变化生成的脚本,通过迁移动作同步到真实数据库中,简而言之,就是实体类属性的增加、移除动作,可通过Migration同步到数据中,相应产生的就是数据库字段的增加与移除动作。
在使用Migration功能之前,必须先要安装相应的nuget包(自行选择合适版本)。
Install-Package Microsoft.EntityFrameworkCore.Tools -Version 2.2.1

指令1: Add-Migration 【名称】

根据类模型类配置定义生成迁移脚本,通常后加一个迁移名称,标识当前类定义生成的最新迁移脚本。使用该指令后迁移脚本会在Migrations 文件夹中自动生成
在这里插入图片描述
在这里插入图片描述
使用Add-Migration update指令后,在Migrations生成了执行编号_Name,执行编号_Name.Designer两个执行脚本。
使用迁移脚本,可以对当前连接的数据库执行编号更高的迁移,这个操作叫做向上迁移(Up),也可以执行把数据库回退到旧的迁移,这个操作叫做向下迁移(Down)。除非有特殊需要,Migration文件下生成的迁移脚本不要轻易去删除。

指令2: Update-Databse

将类型定义变更到数据库中
在这里插入图片描述在这里插入图片描述

5 EFCore与Linq语法的使用

    class Program
    {
        /// <summary>
        /// 使用DbContext实现增删改查;使用对象操作代替数据库中SQL的操作
        /// </summary>
        /// <param name="args"></param>
        static  void Main(string[] args)
        {
            using (MyDbContext context = new MyDbContext()) {

                for (int i = 0; i < 10; i++)
                {
                    LabelConfig c = new LabelConfig();
                    c.ROW_ID = i.ToString();
                    c.SYSTEM_NAME = "test"+ i;
                    c.SYSTEM_GROUP = "test";
                    c.LABEL_NAME = "Label" + i;
                    c.LABEL_DESC = "Label" + i;
                    c.LABEL_LAN = "ef-core-lan" + i;
                    c.CREATE_TIME = DateTime.Now;
                    //插入数据库
                    context.agents.Add(c);
                }
                //异步操作 保存数据表的变更 等价于Update - Database,一定要执行该方法
                Task<int> res = context.SaveChangesAsync();
                int qty = res.Result;
                Console.OutputEncoding = Encoding.Unicode;
                Console.WriteLine($"成功插入{qty}条数据");


                //查询操作,可勇Linq语法,面向对象的操作来代替数据库的SQL操作
                //因为DbContext中DbSet<TEntity>对象是一个继承了IEnumerable<T>的类,可以使用Linq语法来查询符合条件的对象
                //ORM 查询出来的对象对应数据库中指定查询条件的行
                var labels = context.agents.Where(item => item.SYSTEM_GROUP.Equals("test"));
                foreach (LabelConfig label in labels) {
                    Console.WriteLine($"行标为{label.ROW_ID}的LabelName为{label.LABEL_NAME}");
                }


                //数据库update 操作 【update+delete操作】
                //在EFCore中,update动作需要先查询处需要update、delete的数据,再进行update、delete操作,微软官方是为了保证数据库中数据的一致性
                //这种变更操作,意味着批量删除、修改数据库中的数据时,效率低
                var label_0 = context.agents.Where(i => i.LABEL_NAME.Equals("Label0")).First();
                //属性的set操作,等价于 数据库中的update LABEL_LAN='zh-cn'
                label_0.LABEL_LAN = "zh-cn";
                label_0.CREATE_EMP = "F133222X";
                label_0.CREATE_TIME = DateTime.Now;
                res= context.SaveChangesAsync();
                Console.WriteLine($"成功修改了{res.Result}条数据");


                //刪除数据
                var label_1 = context.agents.First(item => item.ROW_ID == "1");
                context.agents.Remove(label_1);
                res= context.SaveChangesAsync();
                Console.WriteLine($"成功删除了{res.Result}条数据");

            }

            Console.ReadKey();
        }
    }

6 查看EFCore生成的SQL

EFCore的核心工作就是将c#代码转化成SQL语句,再交给底层ADO.NET.Core对数据库进行操作。
因此EFCore不是替代ADO.NET.Core的,而是基于ADO.NET.Core之上的,才能与数据库交互操作
在这里插入图片描述

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值