.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 ...
随机推荐
- 最新 蓝鲸人java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿. 蓝鲸人等10家互联网公司的校招Offer,因为某些自身原因最终选择了 蓝鲸人.6.7月主要是做系统复习.项目复盘.Leet ...
- 手把手教你如何安装Tensorflow(Windows和Linux两种版本)
tensorflow 不支持Python2.7,最好选择下载Python3.5 现在越来越多的人工智能和机器学习以及深度学习,强化学习出现了,然后自己也对这个产生了点兴趣,特别的进行了一点点学习,就通 ...
- Django之用户注册
用户注册需要提交的信息包括: 用户名 邮箱 密码 确认密码 验证码 这里选择form表单提交信息,注册页面的响应函数就要分条件执行,get请求时要展示注册页面,post请求时要接收用户提交的信息,对信 ...
- transform-transition-animation(2)
transform transform : none | <transform-function> [ <transform-function> ]* 也就是: transfo ...
- [转帖]理解k8s 的 Ingress
理解k8s 的 Ingress https://www.jianshu.com/p/189fab1845c5/ 暴露一个http服务的方式 service 是 k8s 暴露http服务的默认方式, 其 ...
- 快速搭建ssh项目
环境:oracle11g.myeclipse2014 首先在web项目中添加spring框架 现在已经添加完spring框架了 然后我们开始添加Hibernate框架 到这一步Hibernate框架就 ...
- 解决Html页面缓存
对于一个html页面,缓存分3部分,一个是页面内容,一个是css样式,一个是JS文件 CSS和JS文件缓存 <link rel="stylesheet" type=" ...
- Hibernate持久化,生命周期
一 .生命周期 1.1 . 说明 持久化类就是我们所说的实体类,实体类(持久化类)对象是有状态的. 为什么实体类对象会有状态? 答:由于HIbernate框架是一个先映射,后操作的框架.所谓的状 ...
- flutter从入门到精通四
widget Flutter 从 React 中吸取灵感(如果有react的编程经验,会很容易理解flutter),通过现代化框架创建出精美的组件. 它的核心思想是用 widget 来构建你的 UI ...
- Python-demo(抖音)
# -*- coding:utf-8 -*- from mitmproxy import ctx import json import requests import time import os p ...