这里有一对夫妇为你的 “框架” 的建议。
实体框架
对于每个模型返回从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