zoukankan      html  css  js  c++  java
  • EF Core的Code First 基础

    一.创建实体类与映射类

      通过NuGet引用Microsoft.EntityFrameworkCore

      1.创建实体类

      Code First可以通过为实体类字段添加相应特性,来创建对应的字段类型等,举例如下。

    • [Table]:表名称
    • [Key]:表主键
    • [Column("F_ENCODE", TypeName = "varchar(200)")]:表字段名称和类型
    • [MaxLength]:字符串长度
    • [ForeignKey:表外键约束
    • [NotMapped]:排除该字段,在更新添加时排除
    • [Required]:非空

      但是优先级低于Fluent API 的配置。

      创建实体类,如下:

        [Table("BASE_COMPANY")]
        public class CompanyEntity
        {
            #region  实体成员
            /// <summary>
            /// 公司主键
            /// </summary>
            /// <returns></returns>
            [Key]
            [Column("F_COMPANYID")]
            public string F_CompanyId { get; set; }
            /// <summary>
            /// 公司代码
            /// </summary>
            /// <returns></returns>
            [Column("F_ENCODE", TypeName = "varchar(200)"),Required]
            public string F_EnCode { get; set; }
    
            //此处省略。。。。。
        }

      2.创建映射类

      为每个实体类创建映射类并继承泛型接口IEntityTypeConfiguration<T>,需要实现方法Configure(EntityTypeBuilder<T> builder),通过这个方法可以对每个字段进行主键、类型等配置属于Fluent API,所以会覆盖特性配置。

        public class CompanyMap : IEntityTypeConfiguration<CompanyEntity>
        {
            public void Configure(EntityTypeBuilder<CompanyEntity> builder)
            {
                builder.Property(o => o.F_EnCode).HasMaxLength(12);
                builder.Property(o => o.F_CompanyId).HasMaxLength(12);
            }
        }

     二、创建派生上下文

      1、通过NuGet引用Microsoft.EntityFrameworkCore和Microsoft.EntityFrameworkCore.SqlServer(使用SqlServer数据库,其他数据库引用相应程序包)。

      2、创建继承DbContext的派生上下文,重写方法OnConfiguring(DbContextOptionsBuilder optionsBuilder)和OnModelCreating(ModelBuilder modelBuilder)。

        OnConfiguring:可以配置数据库连接语句、超时重连策略、DbContext行为选择器是否跟踪等。

        OnModelCreating:通过Fluent API配置每个实体类的字段,或者加载需要映射的实体类。

      3、另外可以通过构造函数传入数据库连接的配置,效果同OnConfiguring是一样的。

      此处通过反射动态加载继承IEntityTypeConfiguration<T>实体映射类型

        public class DataBaseContext : DbContext
        {
            public DataBaseContext(DbContextOptions dbContextOptions) : base(dbContextOptions) { }
    
            /// <summary>
            /// 数据库链接配置
            /// </summary>
            /// <param name="optionsBuilder"></param>
            protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            {
                if (!optionsBuilder.IsConfigured)
                {
                    //Add - Migration Init  //其中Init是你的版本名称
                    //update - database Init //更新数据库操作 init为版本名称
                    optionsBuilder.UseSqlServer(Config.Get("ConnectionStrings:BaseDb:ConnectionString"), option => option.UseRowNumberForPaging());
                }
            }
    
            /// <summary>
            /// 模型创建重载
            /// </summary>
            /// <remarks>
            /// 重写DbContext默认的OnModelCreating方法,使用自定义的方法动态加载实体映射类型
            /// </remarks>
            /// <param name="modelBuilder">模型创建器</param>
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                // 通过反射获取继承IEntityTypeConfiguration的实体类型
                string assembleFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("Capricorn.Db.SqlServer.dll", "Capricorn.Entity.Mapping.dll").Replace("file:///", "");
                Assembly asm = Assembly.LoadFile(assembleFileName);
                var configurationTypes = asm.GetTypes()
                    .Where(type => !string.IsNullOrWhiteSpace(type.Namespace))
                    .Where(type => type.GetTypeInfo().IsClass)
                    .Where(type => type.GetTypeInfo().BaseType != null)
                    .Where(type => type.GetInterfaces().Where(o => o.Name == typeof(IEntityTypeConfiguration<>).Name).Count() != 0)
                    .ToList();
                // 实例化实体类加入模型创建器
                foreach (var type in configurationTypes)
                {
                    dynamic obj = Activator.CreateInstance(type);
                    modelBuilder.ApplyConfiguration(obj);
                }
                base.OnModelCreating(modelBuilder);
            }
        }

     三、通过程序包管理器控制台指令创建更新数据库

      add-migration Init 其中Init是你的版本名称,执行之后会生成如下文件:

      update-database Init 更新数据库操作 init为版本名称,执行指定的版本会生成或更新数据库的表、表字段、主外键关系等。

      需要注意通过程序包管理器控制台输入指令前需要将默认项目选择为派生上下文所在的项目。

      并且在Startup.cs的ConfigureServices中初始化数据库上下文。

      //初始化数据库上下文
      services.AddDbContext<DataBaseContext>();

     四、基础增删查改

      由于上面我们将数据库上下文初始化在了Startup.cs中,所以可以用依赖注入的方式获取数据库实例:

            private DataBaseContext context;
            public HomeController(DataBaseContext _context)
            {
                this.context = _context;
            }

      1、查询

      我们采用了通过反射动态映射实体类的方式,所以无法使用一般的直接context.CompanyEntity的这种方式直接查询,需要通过context.Set<T>()。

      获取列表

        var list = context.Set<CompanyEntity>().Where(o => o.F_CompanyId == "123").ToList();

       通过主键获取实体

          var entity = context.Set<CompanyEntity>().Find("123");    

      加载单个实体

        var entity = context.Set<CompanyEntity>().Single(o => o.F_CompanyId == "123");

      2.删除

        CompanyEntity entity = context.Set<CompanyEntity>().Find("123");
           context.Set<CompanyEntity>().Attach(entity);
           context.Set<CompanyEntity>().Remove(entity);
           context.SaveChanges();

      3.添加

        CompanyEntity entity = new CompanyEntity()
        {
          F_CompanyId = "1",
              F_EnCode = "666"
        };
           context.Set<CompanyEntity>().Attach(entity);
           context.Set<CompanyEntity>().Add(entity);
           context.SaveChanges();

      4.更新

        CompanyEntity entity = new CompanyEntity()
        {
          F_CompanyId = "1",
              F_EnCode = "777"
        };
        context.Set<CompanyEntity>().Attach(entity);
        context.Set<CompanyEntity>().Update(entity);
        context.SaveChanges();

      5.执行原始SQL语句

        CompanyEntity entity = context.Set<CompanyEntity>().FromSql("select * from BASE_COMPANY").First();

    五、结束语

      其实EF Core的使用非常的灵活可以有很多种不同的方式,我这里只是其中一种,大家可以可以选择自己喜欢的方式。

      

  • 相关阅读:
    相当当中 ,还用到一个很重要的类 ,map地图类
    使用ObjectDataSource查询和更新
    sqlserver 简单的存储过程学习记录
    一个winform的基于TCP的服务端的GPS平台的网关。利用多线程异步的方式 。
    个人网站准备之数据处理
    记录日志(自治事务
    android调用lua
    CMarkup类读写xml文件
    MyBatis.Net 配置
    NPOI读取Excel到集合对象
  • 原文地址:https://www.cnblogs.com/xwc1996/p/11272740.html
Copyright © 2011-2022 走看看