目录

前言

最近在学习、研究 .NET Core 方面的知识,动手搭建了一些小的 Demo,对 .NET Core 有了初步的认识了解。

恰逢公司的项目需要,有一个需求,不大不小可以作为转 .NET Core 的示例项目来做。

这个项目的搭建工作由我来做,我这边做了一些技术预研,对呀用到的技术进行预研,其中包括:Kafka、SignalR、Topshelf。

但是在做单数据库的时候出现了一些问题。

一、技术选型

这里说的技术选型是数据操作这一块的。

我们之所以选择了 EF、Dapper 结合,是有原因的。以前是直接用的 EF DBFirst 直接拖库过来,用 Linq 语句查询,但是这样对于多张表的连表查询存在很大的隐患,因为这样生成的 SQL 语句不可靠,有时候生成的太复杂,效率太低,所以最终选择了 EF 和 Dapper 结合。对于简单的查询直接用 EF 操作,对于复杂一些的查询写 SQL 语句用 Dapper 查询。

这个选型是原先 .NET 下的,这次转的话,也按照这个来。

二、遇到的坑

在具体的实施中遇到了几个坑,下面就展开说说。

2.1、.NET Core 下 EF 的问题

.NET  Core 下的 EF 和原先平台的有挺大的差别,首先构造函数的差别:

.NET  下的

public DbContext(string nameOrConnectionString);

public DbContext(string nameOrConnectionString, DbCompiledModel model);

public DbContext(DbConnection existingConnection, bool contextOwnsConnection);

public DbContext(ObjectContext objectContext, bool dbContextOwnsObjectContext);

public DbContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection);

protected DbContext();

protected DbContext(DbCompiledModel model);

.NET Core 下的

public DbContext([NotNullAttribute] DbContextOptions options);

protected DbContext();

主要是因为 .NET Core 下功能模块的注册使用的新的方式。

那么在.NET Core 下继承 DbContext 并对其扩展如下:

public class DbContextTest : DbContext
{
public DbContextTest(DbContextOptions<DbContextTest> options)
: base(options)
{
}
}
public class MySQLDatabase
{
#region 构造函数
/// <summary>
/// 构造方法
/// </summary>
/// <param name="connString">连接串</param>
public MySQlDatabase(string connString)
{
var optionBuilder = new DbContextOptionsBuilder<DatabaseContext>();

        optionBuilder.UseMySql(connString, mysqlOptions =>
        {
          mysqlOptions.ServerVersion(new Version(5, 7, 22), Pomelo.EntityFrameworkCore.MySql.Infrastructure.ServerType.MySql);
        });

            dbcontext = new DatabaseContext(optionBuilder.Options);
Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
}      // 这里是扩展的一些方法
}

2.2、数据库实体类的注册

因为选择了 EF 和 Dapper 那么需要自己动态建实体类并注册。

原先写了一个实体类生成的工具,这里拿来直接用了,在注册的时候 EF 和以前的注册方式有了改变,这里有对其扩展的代码:

namespace DataBase.Mapping
{
public interface IEntityMappingConfiguration
{
void Map(ModelBuilder b);
} public interface IEntityMappingConfiguration<T> : IEntityMappingConfiguration where T : class
{
void Map(EntityTypeBuilder<T> builder);
} public abstract class EntityMappingConfiguration<T> : IEntityMappingConfiguration<T> where T : class
{
public abstract void Map(EntityTypeBuilder<T> b); public void Map(ModelBuilder b)
{
Map(b.Entity<T>());
}
} public static class ModelBuilderExtenions
{
private static IEnumerable<Type> GetMappingTypes(this Assembly assembly, Type mappingInterface)
{
return assembly.GetTypes().Where(x => !x.IsAbstract && x.GetInterfaces().Any(y => y.GetTypeInfo().IsGenericType && y.GetGenericTypeDefinition() == mappingInterface));
} public static void AddEntityConfigurationsFromAssembly(this ModelBuilder modelBuilder, Assembly assembly)
{
var mappingTypes = assembly.GetMappingTypes(typeof(IEntityMappingConfiguration<>));
IEnumerable<IEntityMappingConfiguration> configs = mappingTypes.Select(Activator.CreateInstance).Cast<IEntityMappingConfiguration>();
foreach (var config in configs)
{
config.Map(modelBuilder);
}
}
}
}

实体类的 Mapping,这个是继承了上面的接口 :

    public class ApplicationMap : EntityMappingConfiguration<ApplicationEntity>
{
public override void Map(EntityTypeBuilder<ApplicationEntity> b)
{
b.ToTable("application")
.HasKey(p => p.Id);
}
}

那么在 DbContextTest 里面重写 OnModelCreating 方法:

        protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder); string assembleFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("DataBase.dll", "Mapping.dll").Replace("file:///", "");
Assembly asm = Assembly.LoadFile(assembleFileName);
modelBuilder.AddEntityConfigurationsFromAssembly(asm);
}

这样代码工作基本完成了。

切记坑:

开始用的是 MySQL 官方的驱动:MySql.Data.EntityFrameworkCore ,但是一直报错:" The 'MySQLNumberTypeMapping' does not support value conversions. "

后来改用 Pomelo.EntityFrameworkCore.MySql 就可以了。

这个坑困扰了几天,真是憔悴了些。

.NET Core、EF、Dapper、MySQL 多种方式实现数据库操作(动态注册实体类)的更多相关文章

  1. net core天马行空系列-可用于依赖注入的,数据库表和c#实体类互相转换的接口实现

    1.前言 hi,大家好,我是三合.作为一名程序猿,日常开发中,我们在接到需求以后,一般都会先构思一个模型,然后根据模型写实体类,写完实体类后在数据库里建表,接着进行增删改查, 也有第二种情况,就是有些 ...

  2. C#连接Oracle数据库,通过EF自动生成与数据库表相关的实体类

    C#连接Oracle数据库,通过EF自动生成与数据库表相关的实体类 ps:如需转载,请在转载文章明显处,i标注作者和原文地址 一.准备条件 需要自己电脑上已经安装了Oracle数据库,并且已经创建了相 ...

  3. 【.NetCore学习】ASP.NET Core EF Core2.0 DB First现有数据库自动生成实体Context

    主要参考微软官方文档 https://docs.microsoft.com/en-us/ef/core/get-started/aspnetcore/existing-db Microsoft .NE ...

  4. EF Core 2.0中如何手动映射数据库的视图为实体

    由于Scaffold-DbContext指令目前还不支持自动映射数据库中的视图为实体,所以当我们想使用EF Core来读取数据库视图数据的时候,我们需要手动去做映射,本文介绍如何在EF Core中手动 ...

  5. MySql学习 (一) —— 基本数据库操作语句、三大列类型

    注:该MySql系列博客仅为个人学习笔记. 在使用MySql的时候,基本都是用图形化工具,如navicat.最近发现连最基本的创建表的语法都快忘了... 所以,想要重新系统性的学习下MySql,为后面 ...

  6. 使用.net core efcore根据数据库结构自动生成实体类

    源码 github,已更新最新代码 https://github.com/leoparddne/GenEntities/ 使用的DB是mysql,所有先nuget一下mysql.data 创建t4模板 ...

  7. MYSQL初级学习笔记一:MYSQL常用命令和数据库操作(DDL)!(视频序号:初级_3,4)

    知识点一:MYSQL常用命令(3) 登入方法:一,mysql –u 账号 –p 密码 退出方法:一,EXIT,QUIT 修改MYSQL命令提示符: 连接上客户机之后,通常使用prompt命令修改: 连 ...

  8. linux中mysql,mongodb,redis,hbase数据库操作

    .实验内容与完成情况:(实验具体步骤和实验截图说明) (一) MySQL 数据库操作 学生表 Student Name English Math Computer zhangsan lisi 根据上面 ...

  9. net core EF 链接mysql 数据库

    这个主要是一个demo.就在一个工程里面写的 安装MySql.Data.EntityFrameworkCore 增加DbContext 相当于程序与数据库的中间层 public class Ident ...

随机推荐

  1. Adaptive Compressive Tracking via Online Vector Boosting Feature Selection(ACT算法解读)

  2. php面相对象基本概念,基本形式,传值

    面向对象基本概念 面向对象三大特性:封装  继承  多态 类与对象 类:是用于描述“某一些具有共同特征”的物体的概念,是某一类物体的总称. 通常,一个类所具有的共同特征包括2大方面的信息: 外观,形状 ...

  3. Java后台面试之java基础

    经典类概念性问题 1.java支持的数据类型有哪些?什么是自动拆装箱? 12.Java有哪些特性,举个多态的例子. 14.请列举你所知道的Object类的方法. 15.重载和重写的区别?相同参数不同返 ...

  4. 019 Android 形状可绘制对象(根据要求绘制图片)+图片选择器

    1.目标效果 绘制颜色渐变的图片 2.实现方法 (1)在app--->res--->drawable 右击drawable文件夹右键,new ---->drawable resour ...

  5. 【转帖】IP地址总数

    http://blog.sina.com.cn/s/blog_ac1d70a40102xn8z.html 计算规则挺有意思的 私有IP地址段: A类:10.0.0.0到10.255.255.255 1 ...

  6. hdu 6609 区间条件前缀和 + 二分

    题目传送门//res tp hdu 目的 在尾部逐步插入n个元素,求插入第i个元素时,[1,i)内删去多少个元素,可使前缀和[1,i]不大于m 多测Q [1,15] n [1,2e5] m [1,1e ...

  7. PAT甲级题分类汇编——线性

    本文为PAT甲级分类汇编系列文章. 线性类,指线性时间复杂度可以完成的题.在1051到1100中,有7道: 题号 标题 分数 大意 时间 1054 The Dominant Color 20 寻找出现 ...

  8. Linux命令格式及7个常见终端命令

    Linux命令格式 Linux常见的7个终端命令

  9. Arm-Linux 移植 FFMPEG库 + x264

      背景: ffmpeg 中带有264的解码,没有编码,需要添加x264.libx264是一个自由的H.264编码库,是x264项目的一部分,使用广泛,ffmpeg的H.264实现就是用的libx26 ...

  10. 杭电1253 超时的bfs...

    #include<stdio.h>#include<iostream>#include<string.h>#include<algorithm>usin ...