目录

前言

最近在学习、研究 .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. 服务发现框架选型,Consul还是Zookeeper还是etcd

    背景 本文并不介绍服务发现的基本原理.除了一致性算法之外,其他并没有太多高深的算法,网上的资料很容易让大家明白上面是服务发现. 想直接查看结论的同学,请直接跳到文末. 目前,市面上有非常多的服务发现工 ...

  2. JavaScript图形实例:图形的旋转变换

    旋转变换:图形上的各点绕一固定点沿圆周路径作转动称为旋转变换.可用旋转角表示旋转量的大小. 旋转变换通常约定以逆时针方向为正方向.最简单的旋转变换是以坐标原点(0,0)为旋转中心,这时,平面上一点P( ...

  3. 对象的加减乘除运算demo

    1 class Square: 2 def __init__(self, wh): #因为是正方形, 只取一条边的长度 3 if isinstance(wh,(int,float)): 4 self. ...

  4. IDEA 创建JAVA Maven Web 工程 不能建Sevlet文件

    JAVA目录下建包而不是文件夹 需要添加依赖 <dependency> <groupId>javax.servlet</groupId> <artifactI ...

  5. linux 下mongo 基础配置

    配置文件dbpath=/usr/local/mongodb/dblogpath=/usr/local/mongodb/log/mongo.logport=27017fork=truejournal=f ...

  6. ding

    Import "shanhai.lua"Dim currHour,currMinute,currSecondDim mmRnd = 0Dim sumFor=Int(ReadUICo ...

  7. 线性表——顺序表的实现与讲解(C++描述)

    线性表 引言 新生安排体检,为了 便管理与统一数据,学校特地规定了排队的方式,即按照学号排队,谁在前谁在后,这都是规定好的,所以谁在谁不在,都是非常方便统计的,同学们就像被一条线(学号)联系起来了,这 ...

  8. Java静态分派和动态分派

    前言 动态分派和静态分派机制是Java多态实现的原理.本文将针对这两种机制进行浅析. 静态分派 静态分派机制最典型的代码示例如下 void test() { Father father = new S ...

  9. BJFU——205基于顺序存储结构的图书信息表的排序

    #include<stdio.h> #include<stdlib.h> #define MAX 1000 typedef struct{ double no; char na ...

  10. 【已解决】每次打开Excel时会同时打开一个空的Excel表格

    每次打开Excel时会同时打开一个空的Excel表格,情况如图. 官方解法如下,本人验证有效: 方法1, 请到以后路径中检查是否存在与空白文件夹同名字的Excel文件,删除它. C:\Users\\A ...