.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 ...
随机推荐
- servlet中ServletContainerInitializer的简单说明
根据官方文档到的说明 public interface ServletContainerInitializer Interface which allows a library/runtime to ...
- 第5课.linux进阶命令
1.find:查找符合条件的文件 格式: find 目录名 选项 查找条件 eg: find /work/001_linux_basic/dira/ -name "test1.txt&quo ...
- 记一次EFCore类型转换错误及解决方案
一 背景 今天在使用EntityFrameworkCore 查询的时候在调试的时候总是提示如下错误:Unable to cast object of type 'System.Data.SqlTyp ...
- java8 time包的简单使用
import com.sun.org.apache.xml.internal.res.XMLErrorResources_tr; import java.text.DateFormat; import ...
- C++_向函数传递对象
向函数传递对象 1. 使用对象作为函数参数 对象可以作为参数传递给函数,其方法与传递其他类型的数据相同. 在向函数传递对象时,是通过传值调用传递给函数的. 因此,函数中对对象的任何修改均不影响调用该函 ...
- 在做爬虫或者自动化测试时新打开一个新标签页,必须使用windows切换
在做爬虫或者自动化测试时,有时会打开一个新的标签页或者新的窗口,直接使用xpath定位元素会发现找不到元素,在firefox中定位了元素还是找不到, 经过多次发现,在眼睛视野内看到这个窗口是在最前面, ...
- python第二天---字符串的魔法
# "adcbdefg" # "a" # 判断某个东西是否在里面包含 in | not in # name = "abcdefg" # # ...
- 知识不是来炫耀的,而是来分享的-----现在的人们却…似乎开始变味了…
我讨厌那些自以为是的人,哪些只有远大抱负却不付出的混蛋,我讨厌那些老生欺负小生,讨厌以大欺小,讨厌别人把知识拿来炫耀. 我自己也不愿做这类人,我渴望看到成功,我不怕一意孤行,我不怕失败,我只怕自己做的 ...
- c#使用GDI进行简单的绘图
https://www.2cto.com/database/201805/749421.html https://zhidao.baidu.com/question/107832895.html pr ...
- 转 C# GDI+ 实现橡皮筋技术
http://www.cnblogs.com/arxive/p/6080085.html 应该有很多人都在寻找这方面的资料,看看下面我做的,或许对你会有所帮助,但愿如此. 为了实现橡皮筋技术,我用了两 ...