abp mysql 存储过程_使用ABP框架踩过的坑系列5
DDD领域驱动开发,实际是为复杂的业务场景而生的,为了让开发人员专注于业务,而非操作系统、数据库、网络之类的技术细节,必须要持久透明化:实际就是数据库系统DBMS的ORM抽象,目标就是业务不需要考虑数据是如何存储的,业务是独立于DBMS, 通俗讲业务系统不依赖某个DBMS实现,可以通过配置,灵活动态支持各种DBMS,如MS SQL、MySql、Orcacle等。ABP的目标是DDD, 在持久透明化这块,是用IRepository仓储抽象来做的,具体的DBMS实现的ORM就放在基础架构层Infrastructure里。理想是很美好的,实际还是有些坑的,我在做一个项目,当把MSSQL切换到MySql,还是遇到了问题!
public static classDbContextConfigurer
{public static void Configure(DbContextOptionsBuilder builder, stringconnectionString)
{//builder.UseSqlServer(connectionString); //使用MSSQL
builder//.UseLoggerFactory(MyLoggerFactory)
.UseMySql(connectionString); //使用MySql
}public static void Configure(DbContextOptionsBuilderbuilder, DbConnection connection)
{//builder.UseSqlServer(connection);
builder.UseMySql(connection);
}}
用ABP模板生成的项目中,如果使用.netcore和EFcore, 就会有DbContextConfigurer,只要安装了Microsoft.entityframeworkcore.mysql, 就可以使用UseMySql这个扩展方法,
"ConnectionStrings": {//"Default": "Server=localhost; Database=Db3; Trusted_Connection=True;"
"Default": "Server=localhost;port=3306;database=Db3;uid=root;password=root;character set=utf8;Old Guids=true"},
appsettings.json 里ConnectionStrings,也使用Mysql连接字符串,然后再PMC(程序包控制台)执行
update-dabase
完成以上步骤,从MSSQL切换到了Mysql, 大功告成!理想是这样的,事实上也大部分可行,但会报一些莫名其妙的错误:约束错误!这些问题,一度让我很沮丧,甚至想放弃mysql, 迫于linux下装MSSQL的恐怖,还是坚持用mysql, 后在baidu的帮助下,找到了原因:Microsoft.entityframeworkcore.mysql 有问题,必须用melo.EntityFrameworkCore.MySql
然后再PMC(程序包控制台)执行
install-package Pomelo.EntityFrameworkCore.MySql
再执行update-dabase, 真的一切都好了,其实在ORM的抽象和实现方面,ABP都比较好的Module, 当家的是Microsoft的EF
Abp.EntityFrameWork.Common //EF的公共部分
Abp.EntityFrameWork //EF
Abp.EntityFrameWorkCore //EFCore
还有来自Java阵营的
Abp.NHibernate
还有几个比较流行的,
Abp.Dapper //据说性能是ef几十倍的Dapper
Abp.MongoDB //nosql,KV和文档数据库
Abp.MemoryDb //内存数据库,可用于单元测试,棒棒的
个人还是偏爱EF系列,特别是linux下用EFCore+Mysql, 是最佳组合,经过几个项目的实战,证明是个不错选择,可以放心使用!
ABP有关ORM的抽象机制,主要通过Repostitory和UnitOfWork来做的
namespaceAbp.Domain.Repositories
{///
///This interface is implemented by all repositories to ensure implementation of fixed methods. 说白了就是CRUD得封装///
/// Main Entity type this repository works on
/// Primary key type of the entity
public interface IRepository : IRepository where TEntity : class, IEntity{#region Select/Get/Query
...#endregion
#region Insert
...#endregion
#region Update
...#endregion
#region Delete
...#endregion
#region Aggregates
...#endregion}
}
///
///Defines a unit of work.///This interface is internally used by ABP. 实际上就是数据库连接和事务的封装///Useto start a new unit of work.///
public interfaceIUnitOfWork : IActiveUnitOfWork, IUnitOfWorkCompleteHandle
{///
///Unique id of this UOW.///
string Id { get; }///
///Reference to the outer UOW if exists.///
IUnitOfWork Outer { get; set; }///
///Begins the unit of work with given options.///
/// Unit of work options
void Begin(UnitOfWorkOptions options);
具体我们在Service中,只要用DI就可以注入了,其实现机理,以EFCore为例
///
///This module is used to implement "Data Access Layer" in EntityFramework. 类似Mybatis的数据访问层,在ABP中叫基础架构///
[DependsOn(typeof(AbpKernelModule))]public classAbpEntityFrameworkCoreModule : AbpModule
{
。。。private voidRegisterGenericRepositoriesAndMatchDbContexes()
{var dbContextTypes =_typeFinder.Find(type=>type.IsPublic&&
!type.IsAbstract &&type.IsClass&&
typeof(AbpDbContext).IsAssignableFrom(type)
);if(dbContextTypes.IsNullOrEmpty())
{
Logger.Warn("No class found derived from AbpDbContext.");return;
}using (var repositoryRegistrar = IocManager.ResolveAsDisposable())
{foreach (var dbContextType indbContextTypes)
{
Logger.Debug("Registering DbContext:" +dbContextType.AssemblyQualifiedName);
repositoryRegistrar.Object.RegisterForDbContext(dbContextType, IocManager);
}
}
。。。}
}
public classEfCoreGenericRepositoryRegistrar : IEfCoreGenericRepositoryRegistrar, ITransientDependency
{
。。。public voidRegisterForDbContext(Type dbContextType, IIocManager iocManager)
{var autoRepositoryAttr = dbContextType.GetSingleAttributeOrNull() ??EfCoreAutoRepositoryTypes.Default;foreach (var entityTypeInfo inDbContextHelper.GetEntityTypeInfos(dbContextType))
{var primaryKeyType =EntityHelper.GetPrimaryKeyType(entityTypeInfo.EntityType);if (primaryKeyType == typeof(int))
{var genericRepositoryType =autoRepositoryAttr.RepositoryInterface.MakeGenericType(entityTypeInfo.EntityType);if (!iocManager.IsRegistered(genericRepositoryType))
{var implType = autoRepositoryAttr.RepositoryImplementation.GetGenericArguments().Length == 1
?autoRepositoryAttr.RepositoryImplementation.MakeGenericType(entityTypeInfo.EntityType)
: autoRepositoryAttr.RepositoryImplementation.MakeGenericType(entityTypeInfo.DeclaringType, entityTypeInfo.EntityType);
iocManager.Register(
genericRepositoryType,
implType,
DependencyLifeStyle.Transient
);
}
}var genericRepositoryTypeWithPrimaryKey =autoRepositoryAttr.RepositoryInterfaceWithPrimaryKey.MakeGenericType(entityTypeInfo.EntityType, primaryKeyType);if (!iocManager.IsRegistered(genericRepositoryTypeWithPrimaryKey))
{var implType = autoRepositoryAttr.RepositoryImplementationWithPrimaryKey.GetGenericArguments().Length == 2
?autoRepositoryAttr.RepositoryImplementationWithPrimaryKey.MakeGenericType(entityTypeInfo.EntityType, primaryKeyType)
: autoRepositoryAttr.RepositoryImplementationWithPrimaryKey.MakeGenericType(entityTypeInfo.DeclaringType, entityTypeInfo.EntityType, primaryKeyType);
iocManager.Register(
genericRepositoryTypeWithPrimaryKey,
implType,
DependencyLifeStyle.Transient
);
}
}
}
}
整个目的就是为了可以注入泛型的IRepostitory,我们的service,就可以愉快的使用了
public IRepository FoodMaterialRepository { get; set; } //属性注入
//或
private IRepository_categoryRepository;public FoodMaterialAppService(IRepositoryrepository
, IRepositorycategoryRepository)
:base(repository)
{
_categoryRepository=categoryRepository;
}//构造注入
总结:.net 已经拥抱开源和linux了,曾经的四大金刚LAMP(Linux+Apache+Mysql+Php),如今.net也可以Cover了,跨平台(操作系统、数据库等),是一个上线系统的必须,特别部署到云上,linux+mysql的性价比还是比较高的,可真正要做到跨平台和持久透明,在设计DB时,还是要注意:不要用存储过程,所有逻辑必须在代码里完成,DB只是用来存储的;ABP在这个领域,给了我们OutOfBox开箱即用的很多Module, 可以让我们效率大大提升!
abp mysql 存储过程_使用ABP框架踩过的坑系列5相关推荐
- JAVA类似ABP框架_使用ABP框架踩过的坑系列5
DDD领域驱动开发,实际是为复杂的业务场景而生的,为了让开发人员专注于业务,而操作系统.数据库.网络之类的技术细节,必须要持久透明化:实际就是数据库系统DBMS的ORM抽象,目标就是业务不需要考虑数据 ...
- Abp mysql guid_使用ABP框架踩过的坑系列5
public static class DbContextConfigurer { public static void Configure(DbContextOptionsBuilder build ...
- 数据库mysql存储过程_[数据库]mysql存储过程的建立及使用
mysql存储过程的建立及使用 建立存储过程,特别是带有参数的情况反复出错,经常提示"字符串格式不正确",或者是找不到这样,找不到那样,经分细心分析.分步测试,终于上传成功,这里介 ...
- abp执行mysql语句_在ABP模板工程中使用MySql
1 下载一个新的ABP模板项目 http://www.aspnetboilerplate.com/ 2 在Windows上安装MySql, 创建一个新的数据库 sampledb https://dev ...
- abp mysql .net core_基于abp vNext和.NET Core 开发博客
基于 abp vNext 和 .NET Core 开发博客项目>是由智客[阿星Plus](微信公众号:阿星Plus)提供,阅读原文),楠木大叔整理. 此个人博客项目底层基于 ABP Framew ...
- MySQL存储过程_创建-调用
存储过程:SQL中的"脚本" 创建存储过程 调用存储过程 存储过程体 语句块标签 存储过程的参数 in:向过程里传参 out:过程向外传参值 inout:in and out #S ...
- jpa执行mysql存储过程_基于Spring Boot,使用JPA调用Sql Server数据库的存储过程并返回记录集合...
那么,有些情况,会把一些查询语句写在存储过程中,由存储过程来返回记录集. 在这里就先通过EntityManager创建命名存储过程的方法完成调用. 1.创建SQL存储过程 存储过程返回所有的联系人. ...
- mvc调用mysql存储过程_使用.NET MVC +EF调用oracle的存储过程
题记: 需求如题,在网上搜索了一下,没有特别贴合我需求的资料,只好自己摸索,东拼西凑了解了一点东西慢慢尝试做了出来. 难点:.NET是微软产品,主要支持Sql Server数据库,对于Oracle的数 ...
- jpa mysql存储过程_(原)springbootjpa调用服务器mysql数据库的存储过程方法-Go语言中文社区...
一.springboot jpa项目文件配置 #---------------------------------------------------------- ################# ...
最新文章
- 文件到Java中的byte []
- 四则运算2.0版程序
- UVa11019 Matrix Matcher(hash+kmp)
- python中 str.strip()用法
- js发送get、post请求的方法简介
- Codeforces Round #529 (Div. 3) D. Circular Dance
- Go 遍历map时的key随机化问题及解决方法
- android 维语 字体,维语字体手机版下载-维吾尔文字体apk下载 v2.0 安卓版-IT猫扑网...
- python安装apk到手机_python自动安装apk文件
- 软件中的快速原型技术
- 计算机cpu一直超频,电脑卡顿怎么办,CPU超频让老电脑起死回生,大神带你玩转CPU!...
- win10热点开启后,手机可以连上热点但无法连接网络
- vmware虚拟机连不上服务器,VMware虚拟机nat模式连不上网怎么办
- LVGL8.2学习笔记
- 方差分析及其在Excel、SPSS中的应用
- -moz、-ms、-webkit浏览器私有前缀详解,作用、出处
- 【转】本人常用资源整理(ing...)
- 全国主要城市经纬度表
- Bert超长文本分类、文本摘要
- 易语言微凉模块oracle,穿透框架全智能填表微凉网页填表模块及源码