2015-07-11 52 views
2

我工作的一個.NET MVC Web應用程序的設計,並已經確定,我必須要管理33臺(至今)普通MVC web控制器和CRUD操作通用視圖。通過管理我的意思是典型的SQL操作(插入,更新,刪除和查詢)如何實現使用的EntityFramework

16出來的33桌的都是需要與典型的CRUD的形式給出處理的參考表。通過參考表我的意思是表是其他表引用並用於組合(即coutries,國家,城市,貨幣等)

我很新的MVC在.NET中,但已經看到,當你腳手架你得到具有典型的方法控制器:

  • 指數(獲得)
  • 詳細信息(GET)
  • 創建(獲取+後)
  • 編輯(得+後)
  • 刪除(得+崗位)

而且在數據庫方面我計劃有一個使用的EntityFramework實現INSERT,UPDATE典型的DAO,DELETE和LIST(查詢操作)

這裏是我的問題(最後;-)

因爲我的表的50%將用同樣的方法進行視覺和功能管理,並提供相同的CRUD操作是沒有辦法,我可以使用達到最佳的代碼/視圖重用的模式或方法?

我想避免的是腳手架16個實體獲得每16個* 5視圖(創建,刪除,詳細資料,編輯和索引)

是否有可能16個控制器有一個Single Main controller可路由或管理所有這16個實體並調用實體所需的操作?

是否有可能擁有足夠通用的一組視圖(創建,刪除,詳細信息,編輯和索引)來處理這些相同的16個實體?

如果以上兩種情況都可以,我將如何在Web項目配置中佈線佈線,以便仍然能夠爲這16個實體(/ Countries/Edit/5,/ States/Edit/5等)?

這裏是我想我可以做到這一點的一種方法:

  • 有一個抽象/公共基類或接口的所有16個實體與保存,GETALL邏輯和刪除數據庫操作管理的EntityFramework上下文(即IManageData)
  • 有一個EntityDao,使用的EntityFramework調用它實現了IManageData和執行操作的任何類的方法。
  • 有一個抽象/公共基類(網絡控制器)與所有16個實體的CRUD操作,可以調用的IManageData

方法與共同邏輯請幫我驗證/完成我非常草案設計並提出一些警告或更好的方法來實現這一點。

只是爲了在這裏提供一些背景是腳手架EntitieFramework實體與MVC項目計算策略的鏈接https://code.msdn.microsoft.com/MVC5-Demo-with-Entity-c6bc81df

這是一個公認的答案一個非常類似的問題,我想在決定如何實現之前驗證這個。

Generic CRUD controllers and views

+0

https://msdn.microsoft.com/en-US/data/ee712907#codefirst。希望它對你的問題太有幫助了。 – mybirthname

+0

@mybirthname我已經提供了足夠的細節來嘗試縮小它,並確保「通用管理」方法的具體實現。我希望它不會被關閉 –

+0

我個人不喜歡你的鏈接中接受的答案,因爲網絡代碼和數據代碼緊密耦合在該解決方案中 – Disappointed

回答

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); 
} 

這種一般數據層可以與實體框架(在底部代碼示例例如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的模型)Automapper是衆所周知的庫。
我沒有對路由進行任何更改。保留默認值。
希望它有幫助。祝你好運。

+0

嗨, 我有一個問題,我想從我的泛型類得到表: 公共虛擬TEntity GetById(INT ID){ 回報 _db.Set ().FirstOrDefault(C =>((IEntity)C ).Code == id); } 但LINQ的不能投IEntity 公共抽象類BaseRepository :IRepository 其中TEntity:類,其中M:新的() 如果替換:用 「TEntity類」 「TEntity:IEntity」 我有這個錯誤: 類型'TEntity'必須是引用類型才能用作通用類型或方法'System.Data.Entity.DbContext.Set () 中的參數'TEntity'您能幫助我嗎? 謝謝 – user1545810