Asp.net core 如何减少控制器中的冗余?
我使用ASP.NET Core作为Azure应用程序服务应用程序的后端。对于数据库中的每个表,我创建了一个控制器,作为该表的API端点。代码没有问题,但是对于每个控制器,除了Asp.net core 如何减少控制器中的冗余?,asp.net-core,Asp.net Core,我使用ASP.NET Core作为Azure应用程序服务应用程序的后端。对于数据库中的每个表,我创建了一个控制器,作为该表的API端点。代码没有问题,但是对于每个控制器,除了Include(m=>m.)之外,我可以重复相同的逻辑。是否有一种方法可以将所有这些逻辑移到父TableController类中,并在model类中包含Include()方法 以下是一些示例文件: 表控制器(所有API控制器的父类): 使用System.Threading.Tasks; 使用Microsoft.AspNetC
Include(m=>m.)
之外,我可以重复相同的逻辑。是否有一种方法可以将所有这些逻辑移到父TableController
类中,并在model类中包含Include()
方法
以下是一些示例文件:
表控制器(所有API控制器的父类):
使用System.Threading.Tasks;
使用Microsoft.AspNetCore.Mvc
namespace Backend.API
{
public abstract class TableController<T> : Controller
{
// Public Methods
[HttpGet]
[Route("")]
public abstract Task<IActionResult> GetAllAsync();
[HttpPost]
[Route("")]
public abstract Task<IActionResult> CreateAsync([FromBody] T created);
[HttpGet]
[Route("{id}")]
public abstract Task<IActionResult> GetAsync(string id);
[HttpPatch]
[Route("{id}")]
public abstract Task<IActionResult> UpdateAsync(string id, [FromBody] T updated);
[HttpDelete]
[Route("{id}")]
public abstract Task<IActionResult> DeleteAsync(string id);
}
}
示例控制器:
using System;
using System.Threading.Tasks;
using Backend.Models.DB;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Backend.API
{
[Route("tables/BlogPost")]
public class BlogPostController : TableController<BlogPost>
{
// Private Properties
private readonly BadmintonClubDBDataContext _db;
// Constructors
public BlogPostController(BadmintonClubDBDataContext db) => _db = db;
// Overridden Methods
public override async Task<IActionResult> GetAllAsync()
{
var posts = await _db.BlogPosts
.Include(bp => bp.Publisher)
.ToArrayAsync();
return Json(posts);
}
public override async Task<IActionResult> CreateAsync([FromBody] BlogPost created)
{
if (!ModelState.IsValid)
return BadRequest();
BlogPost post = (await _db
.AddAsync(new BlogPost(created))).Entity;
await _db.SaveChangesAsync();
return Json(post);
}
public override async Task<IActionResult> GetAsync(string id)
{
BlogPost post = await _db.BlogPosts
.Include(bp => bp.Publisher)
.SingleOrDefaultAsync(bp => bp.Id == new Guid(id));
if (post == null)
return NotFound();
return Json(post);
}
public override async Task<IActionResult> UpdateAsync(string id, [FromBody] BlogPost updated)
{
BlogPost post = await _db.BlogPosts
.Include(bp => bp.Publisher)
.SingleOrDefaultAsync(bp => bp.Id == new Guid(id));
if (post == null)
return NotFound();
if (post.Id != updated.Id || !ModelState.IsValid)
return BadRequest();
post.Update(updated);
await _db.SaveChangesAsync();
return Json(post);
}
public override async Task<IActionResult> DeleteAsync(string id)
{
BlogPost post = await _db.BlogPosts
.FindAsync(id);
if (post == null)
return NotFound();
_db.BlogPosts.Remove(post);
await _db.SaveChangesAsync();
return Ok();
}
}
}
使用系统;
使用System.Threading.Tasks;
使用Backend.Models.DB;
使用Microsoft.AspNetCore.Mvc;
使用Microsoft.EntityFrameworkCore;
命名空间Backend.API
{
[路线(“表格/博客帖子”)]
公共类BlogPostController:TableController
{
//私有财产
私有只读羽毛球LubdbDataContext_db;
//建设者
公共BlogPostController(羽毛球俱乐部数据库上下文数据库)=>\u db=db;
//重写的方法
公共重写异步任务GetAllAsync()
{
var posts=等待_db.BlogPosts
.Include(bp=>bp.Publisher)
.ToArrayAsync();
返回(员额);
}
公共重写异步任务CreateAsync([FromBody]BlogPost已创建)
{
如果(!ModelState.IsValid)
返回请求();
BlogPost=(等待_db
.AddAsync(新建博客帖子(已创建)).Entity;
等待_db.SaveChangesAsync();
返回Json(post);
}
公共重写异步任务GetAsync(字符串id)
{
BlogPost=wait_db.BlogPost
.Include(bp=>bp.Publisher)
.SingleOrDefaultAsync(bp=>bp.Id==新Guid(Id));
if(post==null)
返回NotFound();
返回Json(post);
}
公共覆盖异步任务UpdateAsync(字符串id,[FromBody]BlogPost更新)
{
BlogPost=wait_db.BlogPost
.Include(bp=>bp.Publisher)
.SingleOrDefaultAsync(bp=>bp.Id==新Guid(Id));
if(post==null)
返回NotFound();
if(post.Id!=updated.Id | |!ModelState.IsValid)
返回请求();
员额更新(更新);
等待_db.SaveChangesAsync();
返回Json(post);
}
公共重写异步任务DeleteAsync(字符串id)
{
BlogPost=wait_db.BlogPost
.FindAsync(id);
if(post==null)
返回NotFound();
_db.BlogPosts.Remove(post);
等待_db.SaveChangesAsync();
返回Ok();
}
}
}
查看示例控制器,我通过
Update()
和构造函数等方法将大部分逻辑移到了模型中。如何将Include()
方法的逻辑也移动到我的模型中?使用实体的func的expression参数声明方法它将允许您在调用方法时传递lambda表达式
public ICollection<TData> FindAll<TInclude>(Expression<Func<TData, TInclude>> include)
{
using (var ctx = new TContext())
{
return ctx.T.Include(include).ToList();
}
}
有关详细信息,请查看
对于表达式检查,如果要加载导航属性,则可以使用表达式作为方法的参数,然后可以将要加载的任何属性作为lambda表达式传递。x=>x.propertyName。请检查这一点,虽然这可能会回答问题,但如果您包括一些关于如何解决问题的解释,这将非常有用。
public ICollection<TData> FindAll<TInclude>(Expression<Func<TData, TInclude>> include)
{
using (var ctx = new TContext())
{
return ctx.T.Include(include).ToList();
}
}
var entityWithNavigationProp = FindAll(entity=>entity.propertyName);