.NET Core、EF、Dapper、MySQL 多种方式实现数据库操作(动态注册实体类)
目录
前言
最近在学习、研究 .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 多种方式实现数据库操作(动态注册实体类)的更多相关文章
- net core天马行空系列-可用于依赖注入的,数据库表和c#实体类互相转换的接口实现
1.前言 hi,大家好,我是三合.作为一名程序猿,日常开发中,我们在接到需求以后,一般都会先构思一个模型,然后根据模型写实体类,写完实体类后在数据库里建表,接着进行增删改查, 也有第二种情况,就是有些 ...
- C#连接Oracle数据库,通过EF自动生成与数据库表相关的实体类
C#连接Oracle数据库,通过EF自动生成与数据库表相关的实体类 ps:如需转载,请在转载文章明显处,i标注作者和原文地址 一.准备条件 需要自己电脑上已经安装了Oracle数据库,并且已经创建了相 ...
- 【.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 ...
- EF Core 2.0中如何手动映射数据库的视图为实体
由于Scaffold-DbContext指令目前还不支持自动映射数据库中的视图为实体,所以当我们想使用EF Core来读取数据库视图数据的时候,我们需要手动去做映射,本文介绍如何在EF Core中手动 ...
- MySql学习 (一) —— 基本数据库操作语句、三大列类型
注:该MySql系列博客仅为个人学习笔记. 在使用MySql的时候,基本都是用图形化工具,如navicat.最近发现连最基本的创建表的语法都快忘了... 所以,想要重新系统性的学习下MySql,为后面 ...
- 使用.net core efcore根据数据库结构自动生成实体类
源码 github,已更新最新代码 https://github.com/leoparddne/GenEntities/ 使用的DB是mysql,所有先nuget一下mysql.data 创建t4模板 ...
- MYSQL初级学习笔记一:MYSQL常用命令和数据库操作(DDL)!(视频序号:初级_3,4)
知识点一:MYSQL常用命令(3) 登入方法:一,mysql –u 账号 –p 密码 退出方法:一,EXIT,QUIT 修改MYSQL命令提示符: 连接上客户机之后,通常使用prompt命令修改: 连 ...
- linux中mysql,mongodb,redis,hbase数据库操作
.实验内容与完成情况:(实验具体步骤和实验截图说明) (一) MySQL 数据库操作 学生表 Student Name English Math Computer zhangsan lisi 根据上面 ...
- net core EF 链接mysql 数据库
这个主要是一个demo.就在一个工程里面写的 安装MySql.Data.EntityFrameworkCore 增加DbContext 相当于程序与数据库的中间层 public class Ident ...
随机推荐
- Adaptive Compressive Tracking via Online Vector Boosting Feature Selection(ACT算法解读)
- php面相对象基本概念,基本形式,传值
面向对象基本概念 面向对象三大特性:封装 继承 多态 类与对象 类:是用于描述“某一些具有共同特征”的物体的概念,是某一类物体的总称. 通常,一个类所具有的共同特征包括2大方面的信息: 外观,形状 ...
- Java后台面试之java基础
经典类概念性问题 1.java支持的数据类型有哪些?什么是自动拆装箱? 12.Java有哪些特性,举个多态的例子. 14.请列举你所知道的Object类的方法. 15.重载和重写的区别?相同参数不同返 ...
- 019 Android 形状可绘制对象(根据要求绘制图片)+图片选择器
1.目标效果 绘制颜色渐变的图片 2.实现方法 (1)在app--->res--->drawable 右击drawable文件夹右键,new ---->drawable resour ...
- 【转帖】IP地址总数
http://blog.sina.com.cn/s/blog_ac1d70a40102xn8z.html 计算规则挺有意思的 私有IP地址段: A类:10.0.0.0到10.255.255.255 1 ...
- hdu 6609 区间条件前缀和 + 二分
题目传送门//res tp hdu 目的 在尾部逐步插入n个元素,求插入第i个元素时,[1,i)内删去多少个元素,可使前缀和[1,i]不大于m 多测Q [1,15] n [1,2e5] m [1,1e ...
- PAT甲级题分类汇编——线性
本文为PAT甲级分类汇编系列文章. 线性类,指线性时间复杂度可以完成的题.在1051到1100中,有7道: 题号 标题 分数 大意 时间 1054 The Dominant Color 20 寻找出现 ...
- Linux命令格式及7个常见终端命令
Linux命令格式 Linux常见的7个终端命令
- Arm-Linux 移植 FFMPEG库 + x264
背景: ffmpeg 中带有264的解码,没有编码,需要添加x264.libx264是一个自由的H.264编码库,是x264项目的一部分,使用广泛,ffmpeg的H.264实现就是用的libx26 ...
- 杭电1253 超时的bfs...
#include<stdio.h>#include<iostream>#include<string.h>#include<algorithm>usin ...