【Design】ASP.NET MVC + EF + AutoMapper + T4 多模型项目设计方案

 

目录

简介

AutoMapper使用

多模型设计思路

多模型项目设计

创建Dto的T4代码

创建ViewModel的T4代码

创建模型映射关系的T4代码

创建模型转换方法的T4代码

AutoMapper初始化设置


 

 

简介

我们最常见项目架构就是三层架构,其中必少不了Model,但在一个项目中,肯定不止用一种模型

比如DataModel(数据模型),Dto(数据传输对象),ViewModel(视图模型)

其中各个模型的作用

DataModel用于DAL层与数据库数据传输

Dto用于BLL层与UI层数据传输

ViewModel用于UI层的输入验证和数据展示

 

可能有人会说,我只用一个模型不行吗?

答案是可以的,只用DataModel也是,但这只是适用于小项目,没有太多数据表。如果有很多表并且字段很多时,传输过程可能就传输了一些无用的数据,这就是Dto解决的问题,当然不止于此。


AutoMapper使用

在模型转化时,手写代码虽然简单但是很枯燥,我们可以使用模型映射工具自动转换模型,AutoMapper就是一个很好的模型映射工具,相信很多人都用过了,不懂的可以点击这里

 

在两个模型的字段类型和名称相同的情况下,处理起来非常简单

只要在Global文件的Application_Start中添加映射关系即可,例如这样

 AutoMapper.Mapper.Initialize(m =>
 {
     m.CreateMap<UserInfo, UserInfoDto>().ReverseMap();
 });

用法,模型的相互转换

UserInfo userInfo = new UserInfo
{
    Id = 1001,
    Name = "haha",
    Pwd = "123",
    Age = 18,
    IsDeleted = false,
    CreatedTime = DateTime.Now
};

UserInfoDto userInfoDto = AutoMapper.Mapper.Map<UserInfoDto>(userInfo);

UserInfo user = AutoMapper.Mapper.Map<UserInfo>(userInfoDto);

 

多模型设计思路

项目设计中使用EF访问数据库,我们可以通过EF获取实体模型的数据,然后通过T4模板自动代码

可以自动生成Dto,ViewModel,还可以自动生成模型映射关系和模型转换方法

 

多模型项目设计

下面只显示Model部分

其中Wang.OA.Model.Conversion存放模型映射关系和模型转换方法

在开发中不可能一次性把Dto,或者ViewModel写好,所以我们可以用partial标记来生成所需的Dto和ViewModel

当然这部分模型只是一个没有任何字段的类,创建Dto和ViewModel还要根据实际的业务来创建

 

创建Dto的T4代码

通过EF获取所有的模型,生成所有的Dto

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#><#@ 
 output extension=".cs"#>
<#
const string inputFile = @"..\\Wang.OA.Model\\DataModel.edmx";

var code = new CodeGenerationTools(this);
var loader = new MetadataLoader(this);
var region = new CodeRegion(this,1);
var ef = new MetadataTools(this);

var ItemCollection = loader.CreateEdmItemCollection(inputFile);
string namespaceName = code.VsNamespaceSuggestion();

var	fileManager = EntityFrameworkTemplateFileManager.Create(this);

#>

namespace Wang.OA.Dto
{
<#
foreach (var entity in ItemCollection.GetItems<EntityType>().OrderBy(e=>e.Name))
{
#>
    public partial class <#=entity.Name#>Dto
    {
    }
<#}#>
}

生成

生成的类就是一个没有任何字段的类

我们可以根据实际情况创建Dto

UserInfoDto

public partial class UserInfoDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Pwd { get; set; }
    public string ShowName { get; set; }
    public string Remark { get; set; }
}

 

创建ViewModel的T4代码

这代码也是类似上面的,上面重复T4代码的就不写了

namespace Wang.OA.ViewModel
{
<#
foreach (var entity in ItemCollection.GetItems<EntityType>().OrderBy(e=>e.Name))
{
#>
    public partial class <#=entity.Name#>ViewModel
    {
    }
<#}#>
}

生成的同样是没有任何字段的类

我们可以添加一个ViewModel类,添加模型验证,例如

public partial class UserInfoViewModel
{
    public int Id { get; set; }
    [Display(Name = "用户名")]
    [Required]
    public string Name { get; set; }
    [Display(Name = "密码")]
    [Required]
    public string Pwd { get; set; }
    [Display(Name = "姓名")]
    public string ShowName { get; set; }
    [Display(Name = "描述")]
    public string Remark { get; set; }
}

 

接下来就是创建模型映射关系了

在Wang.OA.Model.Conversion项目中添加AutoMapper包

AutoMapperConfigMap文件用于创建模型映射关系

Conversion文件用于创建模型转换的方法

 

创建模型映射关系的T4代码

上面重复的省略

using System;
using Wang.OA.Model;
using Wang.OA.Dto;
using Wang.OA.ViewModel;
using AutoMapper;

namespace Wang.OA.Model
{
	public static class AutoMapperConfigMap
	{
		public static Action<IMapperConfigurationExpression> CreateMap()
        {
            Action<IMapperConfigurationExpression> config = m =>
            {
	<#
	foreach (var entity in ItemCollection.GetItems<EntityType>().OrderBy(e=>e.Name))
	{
	#>
			m.CreateMap<<#=entity.Name#>, <#=entity.Name#>Dto>().ReverseMap();
				m.CreateMap<<#=entity.Name#>Dto, <#=entity.Name#>ViewModel>().ReverseMap();
    
	<#}#>
		};
            return config;
        }
	}
}

 

创建模型转换方法的T4代码

如果模型转换方法像上面的写法还是有些麻烦,

UserInfoDto userInfoDto = AutoMapper.Mapper.Map<UserInfoDto>(userInfo);

UserInfo user = AutoMapper.Mapper.Map<UserInfo>(userInfoDto);

如果能写出扩展方法就更好了,像这样

UserInfoDto userInfoDto = userInfo.ToDto();
UserInfo userInfo2 = userInfoDto.ToDataModel();

当然是可以实现的,我们还是用T4代码批量生成、

上面重复的省略

using Wang.OA.Model;
using Wang.OA.Dto;
using Wang.OA.ViewModel;
using AutoMapper;


namespace Wang.OA.Model
{
	public static partial class ModelExtensions
	{
	<#
	foreach (var entity in ItemCollection.GetItems<EntityType>().OrderBy(e=>e.Name))
	{
	#>
	#region <#=entity.Name#> 
		public static <#=entity.Name#>Dto ToDto(this <#=entity.Name#> dataModel) => Mapper.Map<<#=entity.Name#>Dto>(dataModel);
		public static <#=entity.Name#> ToDataModel(this <#=entity.Name#>Dto dto) => Mapper.Map<<#=entity.Name#>>(dto);
		public static <#=entity.Name#>ViewModel ToViewModel(this <#=entity.Name#>Dto dto) => Mapper.Map<<#=entity.Name#>ViewModel>(dto);
		public static <#=entity.Name#>Dto ToDto(this <#=entity.Name#>ViewModel viewModel) => Mapper.Map<<#=entity.Name#>Dto>(viewModel);
		#endregion <#=entity.Name#>
		
	<#}#>
	}
}

生成的代码

一个模型包含了4个方法,分别为

DataModel转Dto

Dto转DataModel

Dto转ViewModel

ViewModel转Dto

 

AutoMapper初始化设置

最后在Global文件的Application_Start中添加AutoMapper的初始化

AutoMapper.Mapper.Initialize(AutoMapperConfigMap.CreateMap());

设计完成

这样使用起来就很舒服了

UserInfo userInfo = new UserInfo()
{
    Id = 1001,
    Name = "haha",
    Pwd = "123",
    ShowName = "哈哈",
    DelFlag = 0,
    Remark="我是哈哈",
    ModfiedOn = DateTime.Now,
    SubTime = DateTime.Now
};

UserInfoDto userInfoDto = userInfo.ToDto();
UserInfo userInfo2 = userInfoDto.ToDataModel();

UserInfoViewModel userInfoViewModel = userInfoDto.ToViewModel();
UserInfoDto userInfoDto2 = userInfoViewModel.ToDto();

 

如果大家觉得写的不好的,大家多多指教,谢谢。

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页