前言
什么是ORM,即Object-Relationl Mapping,它的作用是在关系型数据库和对象之间作一个映射,将内存中的数据存储在关系型的数据库中,实现了数据处理层内部的业务逻辑和数据逻辑分离的解耦合。
这样,在操作数据库上,我们就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了 。
有一些是该部分所完全必备的dll,有直接提供下载,另外的必要的dll,在整个项目完成之后,会随整个项目一起提供下载,到时候可以对应查看。
准备
在建立关系型数据库和对象之间的映射之前,需要编写一些通用代码,用于将数据库的信息(表,描述,字段等)读取出来,并生成对应的类
1、生成数据库表对应的名称,描述,字段相关信息
//数据库连接字符串
public EFSQLToCode(string sqlCon)
{
this.sqlCon = sqlCon;
}
//获取字段描述
public string GetColumnDesc(string tableName, string ColumnName)
{
CodeModel model = (from o in this.TableColumns()
where (o.TableName == tableName) && (o.ColumnName == ColumnName)
select o).FirstOrDefault<CodeModel>();
if ((model != null) && !string.IsNullOrEmpty(model.ColumnDesc))
{
return model.ColumnDesc;
}
return "";
}
完整代码可下载:Common.EFCode.dll
2、数据库增、删、改、查接口
/// <summary>
/// 新增接口
/// </summary>
/// <typeparam name="T">输出对象</typeparam>
public interface IAdd<T> where T: class, new()
{
/// <summary>
/// 新增
/// </summary>
/// <param name="entity">实体</param>
/// <param name="commit"></param>
/// <returns>返回受影响行数</returns>
void Add(T entity, bool commit = false);
}
完整代码可下载: Common.IDBUtility.dll
3、跟踪在业务交易过程中可能影响数据库的所有操作
/// <summary>
/// 创建工作单元的工厂
/// </summary>
public interface IUnitOfWorkFactory
{
/// <summary>
/// 使用默认设置创建工作单元的实例。
/// </summary>
/// <returns>工作单元的实例。</returns>
IUnitOfWork Create();
/// <summary>
/// 使用指定的数据库连接串创建工作单元的实例。
/// </summary>
/// <param name="connectionString">数据库连接串。</param>
/// <returns>工作单元的实例。</returns>
IUnitOfWork Create(string connectionString);
/// <summary>
/// 使用默认配置创建工作单元的实例。
/// </summary>
/// <param name="Name">数据库连接串名称。</param>
/// <returns>工作单元的实例。</returns>
IUnitOfWork CreateForConnectionStrings(string Name);
}
完整代码可下载:Common.Interfaces.dll
4、EntityFramework.dll,EntityFramework.Extended.dll,EntityFramework.SqlServer.dll
可以通过“管理NuGet包”自动获取
ORM
项目结构:
引入相关dll
1.Common.EFCode:获取数据库信息
2.Common.IDBUtility:增删改查接口
3.Common.Interfaces:ORM工作单元接口
4.Common.Model:状态服务
5.Common.PlatformMessage:通用信息处理类库(后面会讲)
6.Common.Utils:通用核心类库(后面会讲)
7.EntityFramework
8.EntityFramework.Extended
9.EntityFramework.SqlServer
新建ADO.NET实体数据模型(DAL.DALData目录)
1、新建DataModel.edmx,设置关联数据库,选择关联数据表,视图,存储过程等
2、将原有的tt文件,修改为Model.Context.tt(修改方便)
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF6.Utility.CS.ttinclude"#><#@
output extension=".cs"#>
<#
string Namespace="Data";
string inputFile =Namespace+@"Model.edmx";//关键:对应上述的ADO.NET实体数据模型DataModel.edmx
var textTransform = DynamicTextTransformation.Create(this);
var code = new CodeGenerationTools(this);
var ef = new MetadataTools(this);
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
var itemCollection = loader.CreateEdmItemCollection(inputFile);
var modelNamespace = loader.GetModelNamespace(inputFile);
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
var container = itemCollection.OfType<EntityContainer>().FirstOrDefault();
if (container == null)
{
return string.Empty;
}
详细的T4模板语法,可自行学习
3、创建UnitOfWorkFactory类:主要是对接操作数据库类的工作单元工厂
IDAL目录
1、IDALBase.cs:继承自Common.IDBUtility的接口
public interface IDALBase<T> : IAdd<T>, IUpdate<T>, IDelete<T>, ISelectAll<T>
where T : class, new()
{
//void Refresh(RefreshMode refreshMode, object entity);
/ <summary>
/ 使用数据库中的数据更新对象上下文中的对象集合
/ </summary>
/ <param name="refreshMode">一个 System.Data.Entity.Core.Objects.RefreshMode 值,指示是否使用数据库中的属性值重写对象上下文中的属性更改</param>
/ <param name="collection">要刷新的对象的 System.Collections.IEnumerable 集合</param>
/ <exception cref="System.ArgumentNullException"></exception>
//void Refresh(RefreshMode refreshMode, IEnumerable collection);
MutualService.Data.DAL.DALData.DataEntities Db { get; }
}
2、IDAL.tt:生成的类库继承自IDALBase
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@
output extension=".cs"#>
<#
string Namespace="Data"; // TODO:DAL接口的命名空间,根据项目的需要可在T4模板里进行修改。
string entityNamespace="MutualService."+Namespace+".Model"; // TODO:实体类的命名空间,根据项目的需要可在T4模板里进行修改。
#>
<#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);
string inputFile = @"..\DALData\DataModel.edmx";
EdmItemCollection ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();
EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
// Write out support code to primary template output file
WriteHeader(fileManager);
BeginNamespace(namespaceName, code);
WriteCustomObservableCollection();
EndNamespace(namespaceName);
// Emit Entity Types
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
fileManager.StartNewFile("IDAL"+entity.Name + ".partial.cs");
BeginNamespace(namespaceName, code);
bool entityHasNullableFKs = entity.NavigationProperties.Any(np => np.GetDependentProperties().Any(p=>ef.IsNullable(p)));
#>
3、IDalFactory.cs:业务工厂接口
/// <summary>
/// DAL 工厂接口。
/// </summary>
public interface IDalFactory {
Common.Interfaces.IUnitOfWorkFactory CreateOfWorkFactory();
/// <summary>
/// 后台操作角色成员接口
/// </summary>
IDALPermissionsMembersRole CreateDalPermissionsMembersRole(IUnitOfWork iUnitOfWork);
}
未完待续,请接着看下一篇…