gpt4 book ai didi

c# - 在 .NET Core 下的分层架构中自动创建 CRUD

转载 作者:可可西里 更新时间:2023-11-01 08:46:37 30 4
gpt4 key购买 nike

我正在一个典型的三层架构下的新项目中工作:businessdataclient,使用 Angular 作为前端。

在这个项目中,我们将有一个我们想要自动化的重复性任务:CRUD 的创建。我们要做的是生成模型和 Controller (放置、获取、发布、删除)以及来自实体及其属性的其他基本项目信息。

我最好的选择是什么?我曾考虑过模板 T4,但我对它们的无知使我怀疑它是否是最佳选择。

例如,来自这个实体:

public class User
{

public int Id { get; set; }

public string Name {get;set;}

public string Email{ get; set; }

public IEnumerable<Task> Task { get; set; }
}

我想生成以下模型:

public class UserModel
{

public int Id { get; set; }

public string Name {get;set;}

public string Email{ get; set; }

public IEnumerable<Task> Task { get; set; }
}

还有 Controller :

{
/// <summary>
/// User controller
/// </summary>
[Route("api/[controller]")]
public class UserController: Controller
{
private readonly LocalDBContext localDBContext;
private UnitOfWork unitOfWork;

/// <summary>
/// Constructor
/// </summary>
public UserController(LocalDBContext localDBContext)
{
this.localDBContext = localDBContext;
this.unitOfWork = new UnitOfWork(localDBContext);
}

/// <summary>
/// Get user by Id
/// </summary>
[HttpGet("{id}")]
[Produces("application/json", Type = typeof(UserModel))]
public IActionResult GetById(int id)
{
var user = unitOfWork.UserRepository.GetById(id);
if (user == null)
{
return NotFound();
}

var res = AutoMapper.Mapper.Map<UserModel>(user);
return Ok(res);
}

/// <summary>
/// Post an user
/// </summary>
[HttpPost]
public IActionResult Post([FromBody]UserModel user)
{
Usuario u = AutoMapper.Mapper.Map<User>(user);
var res = unitOfWork.UserRepository.Add(u);

if (res?.Id > 0)
{
return Ok(res);
}

return BadRequest();

}

/// <summary>
/// Edit an user
/// </summary>
[HttpPut]
public IActionResult Put([FromBody]UserModel user)
{
if (unitOfWork.UserRepository.GetById(user.Id) == null)
{
return NotFound();
}

var u = AutoMapper.Mapper.Map<User>(user);

var res = unitOfWork.UserRepository.Update(u);

return Ok(res);

}

/// <summary>
/// Delete an user
/// </summary>
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{

if (unitOfWork.UserRepository.GetById(id) == null)
{
return NotFound();
}

unitOfWork.UserRepository.Delete(id);

return Ok();

}

此外,我们需要添加 AutoMapper 映射:

public AutoMapper()
{
CreateMap<UserModel, User>();
CreateMap<User, UserModel>();
}

和工作单元:

private GenericRepository<User> userRepository;

public GenericRepository<User> UserRepository
{
get
{

if (this.userRepository== null)
{
this.userRepository= new GenericRepository<User>(context);
}
return userRepository;
}
}

大多数结构将是相同的,除了一些必须手动完成的 Controller 的特定情况。

最佳答案

这是项目的简化版本,您需要编写该版本才能生成以前的代码。首先创建一个目录,任何 future 的实体都将进入其中。为了简单起见,我将目录命名为 Entities 并创建了一个名为 User.cs 的文件,其中包含 User 类的源代码。

为每个模板创建一个 .tt 文件,该文件以实体名称开头,后跟函数名称。因此,用户模型的 tt 文件将称为 UserModel.tt,您将模型模板放入其中。对于用户 Controller ,USerController.tt,您将在其中放置 Controller 模板。只有 automapper 文件,用户通用存储库将被称为 UserGenericRepository.tt(您已经猜到了)您将通用存储库模板放入其中

模型模板

<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#
var hostFile = this.Host.TemplateFile;
var entityName = System.IO.Path.GetFileNameWithoutExtension(hostFile).Replace("Model","");
var directoryName = System.IO.Path.GetDirectoryName(hostFile);
var fileName = directoryName + "\\Entities\\" + entityName + ".cs";
#>
<#= System.IO.File.ReadAllText(fileName).Replace("public class " + entityName,"public class " + entityName + "Model") #>

我注意到源文件没有命名空间或使用,因此如果不将使用添加到 User.cs 文件,UserModel 文件将无法编译,但是文件确实按照规范生成

Controller 模板

<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#
var hostFile = this.Host.TemplateFile;
var entityName = System.IO.Path.GetFileNameWithoutExtension(hostFile).Replace("Controller","");
var directoryName = System.IO.Path.GetDirectoryName(hostFile);
var fileName = directoryName + "\\" + entityName + ".cs";
#>
/// <summary>
/// <#= entityName #> controller
/// </summary>
[Route("api/[controller]")]
public class <#= entityName #>Controller : Controller
{
private readonly LocalDBContext localDBContext;
private UnitOfWork unitOfWork;

/// <summary>
/// Constructor
/// </summary>
public <#= entityName #>Controller(LocalDBContext localDBContext)
{
this.localDBContext = localDBContext;
this.unitOfWork = new UnitOfWork(localDBContext);
}

/// <summary>
/// Get <#= Pascal(entityName) #> by Id
/// </summary>
[HttpGet("{id}")]
[Produces("application/json", Type = typeof(<#= entityName #>Model))]
public IActionResult GetById(int id)
{
var <#= Pascal(entityName) #> = unitOfWork.<#= entityName #>Repository.GetById(id);
if (<#= Pascal(entityName) #> == null)
{
return NotFound();
}

var res = AutoMapper.Mapper.Map<<#= entityName #>Model>(<#= Pascal(entityName) #>);
return Ok(res);
}

/// <summary>
/// Post an <#= Pascal(entityName) #>
/// </summary>
[HttpPost]
public IActionResult Post([FromBody]<#= entityName #>Model <#= Pascal(entityName) #>)
{
Usuario u = AutoMapper.Mapper.Map<<#= entityName #>>(<#= Pascal(entityName) #>);
var res = unitOfWork.<#= entityName #>Repository.Add(u);

if (res?.Id > 0)
{
return Ok(res);
}

return BadRequest();

}

/// <summary>
/// Edit an <#= Pascal(entityName) #>
/// </summary>
[HttpPut]
public IActionResult Put([FromBody]<#= entityName #>Model <#= Pascal(entityName) #>)
{
if (unitOfWork.<#= entityName #>Repository.GetById(<#= Pascal(entityName) #>.Id) == null)
{
return NotFound();
}

var u = AutoMapper.Mapper.Map<<#= entityName #>>(<#= Pascal(entityName) #>);

var res = unitOfWork.<#= entityName #>Repository.Update(u);

return Ok(res);

}

/// <summary>
/// Delete an <#= Pascal(entityName) #>
/// </summary>
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{

if (unitOfWork.<#= entityName #>Repository.GetById(id) == null)
{
return NotFound();
}

unitOfWork.<#= entityName #>Repository.Delete(id);

return Ok();

}
}
<#+
public string Pascal(string input)
{
return input.ToCharArray()[0].ToString() + input.Substring(1);
}
#>

AutoMapper 的模板

<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#
var directoryName = System.IO.Path.GetDirectoryName(this.Host.TemplateFile) + "\\Entities";
var files = System.IO.Directory.GetFiles(directoryName, "*.cs");
#>
public class AutoMapper
{
<#
foreach(var f in files)
{
var entityName = System.IO.Path.GetFileNameWithoutExtension(f);
#>
CreateMap<<#= entityName #>Model, <#= entityName #>>();
CreateMap<<#= entityName #>, <#= entityName #>Model>();
<#
}
#>}

这基本上遍历 Entities 文件夹中的每个文件并在实体和实体模型之间创建映射器

通用存储库的模板

<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#
var hostFile = this.Host.TemplateFile;
var entityName = System.IO.Path.GetFileNameWithoutExtension(hostFile).Replace("GenericRepository","");
var directoryName = System.IO.Path.GetDirectoryName(hostFile);
var fileName = directoryName + "\\" + entityName + ".cs";
#>
public class GenericRepository
{
private GenericRepository<<#= entityName #>> <#= Pascal(entityName) #>Repository;

public GenericRepository<<#= entityName #>> UserRepository
{
get
{
if (this.<#= Pascal(entityName) #>Repository == null)
{
this.<#= Pascal(entityName) #>Repository = new GenericRepository<<#= entityName #>>(context);
}
return <#= Pascal(entityName) #>Repository;
}
}
}<#+
public string Pascal(string input)
{
return input.ToCharArray()[0].ToString() + input.Substring(1);
}
#>

关于c# - 在 .NET Core 下的分层架构中自动创建 CRUD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50345097/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com