我正在研究.NET MVC WEB应用程序的设计,并确定我必须管理33个表(到目前为止)。通过管理我的意思是典型的SQL操作(插入,更新,删除和查询)
这33个表中有16个是需要使用典型CRUD方法处理的参考表。参考表我指的是其他表格引用并在组合中使用的表格(即国家,州,城市,货币等)
我对.NET中的MVC很新,但是看到当你使用脚手架时,你会得到具有典型方法的控制器:
同样在数据库方面,我计划使用EntityFramework实现INSERT,UPDATE,DELETE和LIST(查询操作)的典型DAO
以下是我的问题(最后; - )
由于50%的表格将以相同的方式在视觉和功能上进行管理并提供相同的CRUD操作是否有一种模式或方法可以实现最佳的代码/视图重用?。
我想避免的是脚手架16个实体来获得16个控制器,每个控制器有16 * 5个视图(创建,删除,细节,编辑和索引)
是否可以让Single Main controller
能够路由或管理所有这16个实体并调用实体所需的操作?
是否可以拥有足够通用的一组视图(创建,删除,详细信息,编辑和索引)来处理这16个实体?
如果以上两个是可能的,我将如何在Web项目的配置中连接路由,以便仍然能够为这16个实体中的每一个提供特定的URL(/ Countries / Edit / 5,/ States / Edit / 5等等)
以下是我认为可以实现这一目标的一种方式:
请帮我验证/完成我的设计草案,并提出一些注意事项或更好的方法来实现这一目标。
这里提供一些上下文是一个关于脚手架EntitieFramework实体与MVC项目https://code.msdn.microsoft.com/MVC5-Demo-with-Entity-c6bc81df
的approch的链接这是一个非常类似的问题,我接受的答案是在确定如何实现这一目标之前要验证的。
答案 0 :(得分:5)
我之前的项目情况类似。我是这样做的。这是每个实体(表)的通用接口
public interface IRepository<T>
{
void Add(T entity, User initiator);
void Update(T entity, User initiator);
void Delete(T entity);
void Delete(int entityId);
IEnumerable<T> GetAll();
T GetById(int entityId);
}
可以使用Entity Framework(底部的代码示例,例如here )或使用不同的方法(在我的情况下,存储过程)轻松实现此常规数据层
我实际上没有任何额外的业务逻辑,所以我的web项目可以直接访问数据存储库。所以这是我的通用基础控制器
public abstract class BaseController<T, M> : Controller
where M : new()
{
public BaseController(IRepository<T> repository)
{
this._repository = repository;
ViewBag.CurrentUser = CurrentUser;
}
protected User CurrentUser
{
get
{
if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{
return Mapper.Map<User>(System.Web.HttpContext.Current.User.Identity);
}
return null;
}
}
protected virtual int PageSize
{
get { return 5; }
}
protected IRepository<T> _repository;
public virtual ActionResult Index(int? currentPage)
{
var entities = _repository.GetAll();
List<M> model = new List<M>();
foreach (var currentEntity in entities)
{
model.Add(Mapper.Map<M>(currentEntity));
}
int pageNumber = (currentPage ?? 1);
return View(model.ToPagedList(pageNumber, PageSize));
}
[HttpGet]
public virtual ActionResult Add()
{
return View(new M());
}
[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public virtual ActionResult Add(M model)
{
if (ModelState.IsValid)
{
_repository.Add(Mapper.Map<T>(model), CurrentUser);
return RedirectToAction("Index");
}
return View(model);
}
[HttpGet]
public virtual ActionResult Update(int modelId)
{
T domainModelEntity = _repository.GetById(modelId);
M model = Mapper.Map<M>(domainModelEntity);
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public virtual ActionResult Update(M model)
{
if (ModelState.IsValid)
{
_repository.Update(Mapper.Map<T>(model), CurrentUser);
return RedirectToAction("Index");
}
return View(model);
}
public virtual ActionResult Delete(int modelId)
{
_repository.Delete(modelId);
return RedirectToAction("Index");
}
}
这个特定的控制器
public class WebPagesController : BaseWebEntityController<WebPage, WebPageModel>
{
public WebPagesController(IRepository<WebPage> repository)
: base(repository)
{
}
}
一点解释。 a)您应该使用一些IOC进行控制器依赖性解析.b)T表示来自数据库(表)的实体,M表示返回给View.c的Model。)Automapper是众所周知的库。
我没有对路由做任何更改。保持默认。
希望能帮助到你。祝你好运。