這裏有一對夫婦爲你的 「框架」 的建議。
實體框架
對於每個模型返回從EF回來,提取EF模型的接口,並使用接口作爲數據源,而不是實現EF類。原因在於,如果您決定爲任何一個或多個模型(或整個實體框架)使用其他數據源,則可以簡單地確保您的新數據層返回相同的接口,而無需更改整個Web碼。缺點是確保您的界面在更改模型時保持最新。
這還允許您的視圖模型實現EF模型的界面(使用您選擇的其他邏輯)。如果您對數據層的插入/更新的所有調用都接受返回的相同接口模型,則這是有利的。這允許您創建具有不同需求的多個模型,這些模型都適合數據層需要插入/更新的內容。缺點是在你的數據層中,你必須[創建一個新的EF模型]/[獲取模型更新]並將界面中的字段映射到模型。
視圖模型
我強烈建議每個視圖模型是不是需要顯示的實際模型(一個或多個),但包含模型(一個或多個)類。示例:
public class Car //Not what I recommend passing to a view
{
public string Make { get; set; }
public string Model { get; set; }
}
//Pass this to the view, i'll explain why...
public class CarViewModel : IPartialViewCar {
public Car Car { get; set; }
public ColorCollection { get; set; }
}
通過傳遞示例「CarViewModel」,可以將部分視圖與視圖分離。以下是如何(使用以上型號):
public interface IPartialViewCar
{
public Car { get; }
}
[BuildCar.cshtml]
@Model MyNameSpace.Models.Car
@Html.EditorFor(model)
[PartialViewCar.cshtml]
@Model MyNameSpace.Models.IPartialViewCar
@Html.EditorFor(model) //something like that..
現在,只要你想使用的PartialViewCar
你只需要做出一個實現IPartialViewCar
界面模型,基本上去耦從視圖中partialview。
驗證
我建議創建接口(類,如果你真的想,但是是不是真的有必要)有大家驗證邏輯。假設我們要求匿名用戶輸入品牌和型號,但註冊用戶只需輸入一個品牌。怎麼可以這樣很容易做到,方法如下:(擴展更多的以前的代碼)
public interface IAnonymouseCarValidation
{
[required]
public string Make { get; set; }
[required]
public string Model { get; set; }
}
public interface IRegisteredCarValidation
{
[required]
public string Make { get; set; }
}
public interface ICar
{
public string Make { get; set;}
public string Model { get; set; }
}
[updating the Car model to abstract and use an interface now]
public abstract class Car : ICar
{
//maybe some constructor logic for all car stuff
public string Make { get; set;}
public string Model { get; set; }
//maybe some methods for all car stuff
}
//MetadataType tells MVC to use the dataannotations on the
//typeof class/interface for validation!
[MetadataType(typeof(AnonymouseCarValidation))]
public class AnonymousCar : Car
{
}
[MetadataType(typeof(AnonymouseCarValidation))]
public class RegisteredCar : Car
{
}
[Now update the ViewModel]
public class CarViewModel : IPartialViewCar
{
public ICar Car { get; set; } //this is now ICar
public ColorCollection { get; set; }
}
現在,您可以創建一個AnonymouseCar
或RegisteredCar
,它傳遞到CarViewModel,讓MVC採取驗證照顧。當您需要更新驗證時,您需要更新單個界面。這個缺點是感覺相當複雜。
注射&數據請求
我的選擇是儘量保持控制器操作儘可能簡單和不包含的代碼有檢索數據。我選擇不這樣做的原因是我不喜歡重複代碼。例如:
public class AccountControllers
{
DataServer _Service;
public AccountControllers(DataServer Service)
{
this._Service = Service;
}
public ActionResult ShowProfiles()
{
ProfileViewModel model = new ProfileViewModel();
model.Profiles = this._Service.Profiles();
return View(model);
}
public ActionResult UpdateProfile(ProfileViewModel updatedModel)
{
service.UpdateProfile(updatedModel);
ProfileViewModel model = new ProfileViewModel();
model.Profiles = this._Service.Profiles();
return View(model);
}
}
相反,我會做這樣的事情:(不完全)
public ActionResult ShowProfile(Guid ID)
{
ProfileViewModel model = new ProfileViewModel(this._service);
return View(model);
}
public ActionResult UpdateProfile(ProfileViewModel updatedModel)
{
// pass in the service, or use a property or have SetService method
updatedModel.Update(this._service)
ProfileViewModel model = new ProfileViewModel(this._service);
return View(model);
}
public class ProfileViewModel()
{
DataServer _Service;
Profile _Profile
public ProfileViewModel()
{
}
public ProfileViewModel(DataServer Service)
{
this._Service = Service;
}
public Profile Profiles()
{
get
{
if (this._service == null)
{
throw new InvalidOperationException("Service was not set.");
}
return = Service.Profiles(ID);
}
這意味着,型材枚舉ONLY時,它的要求,我沒有來填充它自己。如果我使用代碼來獲得優勢,那麼往往會減少錯誤,而不是要求我或其他程序員手動填充模型。
你需要花一些時間閱讀你的問題。用段落格式化它。只列出那些相關的類。 – jgauffin