嗨,我有用 MVC 编写的模型类。我使用的是 Ef 数据库优先方法。在模型类中,我有一些处理数据库的查询。我有以下问题:
1)在模型中使用与数据库相关的查询并在控制器或视图中调用它是正确的方法吗?
2)如果是,我应该在哪里调用这个模型?在控制器或视图中??
3)我应该如何称呼这个模型?比如说我在模型中有一个名为 class1.cs 的类。我应该如何调用这个模型?
嗨,我有用 MVC 编写的模型类。我使用的是 Ef 数据库优先方法。在模型类中,我有一些处理数据库的查询。我有以下问题:
1)在模型中使用与数据库相关的查询并在控制器或视图中调用它是正确的方法吗?
2)如果是,我应该在哪里调用这个模型?在控制器或视图中??
3)我应该如何称呼这个模型?比如说我在模型中有一个名为 class1.cs 的类。我应该如何调用这个模型?
您的模型包含定义项目中不同对象的类。这包括属性及其基本信息和对此对象执行操作的方法。
1)你真的需要查询吗?为什么不使用实体框架来为您做这件事?为您的域类创建映射(槽注释或流式 api)并使用它DbContext
来检索和保存存储在数据库中的数据
2) 理想情况下,人们会创建注入到控制器中的存储库(依赖注入)。例如,这些存储库可以包含类似GetPersonById(int id)
. 在这个方法里面会有两件事:
DbContext
例如:
public void Subscribe(int userID, Show show) {
var user = GetUserByID(userID);
if (!user.IsSubscribedTo(show.ShowID)) {
user.Subscribe(show);
_dbContext.SaveChanges();
}
}
控制器 -> 存储库中的方法调用 -> 对相应的域对象执行操作 -> 将更改保存到数据库
如果您需要不需要对象突变的东西,那就更简单了:
public User GetUserByID(int id) {
return _dbContext.Users.FirstOrDefault(x => x.ID == id);
}
3) 槽存储库(见上文)。您DbContext
将拥有一堆DbSets
包含与数据库中每个数据条目相对应的对象。通过存储库,您可以使用这些对象并操作它们。当您调用该DbContext.SaveChanges()
方法时,它将查看这些列表中发生的更改并将更改提交到您的数据库。
存储库示例:
class User {
public int ID { get; set; }
public string Name { get; set; }
}
class DatabaseContext : DbContext {
public DbSet<User> Users { get; set; }
}
public interface IUserRepository {
User GetUserByID (int id);
bool UsernameExists (string name);
}
public class UserRepository : IUserRepository {
private DatabaseContext _db;
public UserRepository(DatabaseContext db){
_db = db;
}
public User GetUserByID(int id) {
return _db.Users.FirstOrDefault(x => x.ID == id);
}
public User GetUserByUsername(string username) {
return _db.Users.FirstOrDefault(x => x.Name == username);
}
}
public class UserController : Controller {
private IUserRepository _userRepository;
public UserController(IUserRepository userRepository) {
_userRepository = userRepository;
}
public ActionResult Details(int id){
return View(_userRepository.GetUserByID(id);
}
}
// Ninject settings (install this extension, you want it):
private void AddBindings(){
kernel.Bind<DatabaseContext>().ToSelf().InSingletonScope();
kernel.Bind<IUserRepository>().To<UserRepository>().InRequestScope();
}
1)在模型中使用与数据库相关的查询并在控制器或视图中调用它是正确的方法吗?
我建议不要直接访问模型类中的数据库,因为您必须记住 MVC 严格来说是一种表示层模式。如果您确实将数据库访问逻辑放在模型类中,那么您将无法让任何其他客户端使用此功能,例如 Web 服务。取而代之的是,将在 ASP.NET MVC 项目之外定义的业务对象转换为 ASP.NET MVC 模型类的逻辑。
这就是 n 层架构的强大之处,如果你创建一个业务和数据访问层,那么我可以编写一个 ASP.NET MVC 前端、WebForms 前端、WPF 前端、WinForms 前端他们都可以使用相同的服务访问数据。通过将逻辑放入 ASP.NET MVC 模型类中,您实际上是在强制任何其他客户端在其类中再次复制该逻辑。
您可以使用某种工作单元模式,将其注入控制器构造函数中,使用控制容器反转 (IOC),例如 autofac。
您的工作单元类可以包含对存储库的引用,您可以在其中查询/插入数据。
大致;
public class BackendController : Controller
{
private UnitOfWork _worker;
public BackendController(UnitOfWork worker)
{
this._worker = worker;
}
public ActionResult Admin()
{
var items = _worker.MyRepository.GetAll();
return View(items);
}
}
public class UnitOfWork
{
private ContentRepository _contentRepository;
public UnitOfWork()
{
}
public ContentRepository MyRepository
{
get
{
if (_contentRepository != null)
return _contentRepository;
else
return _contentRepository = new ContentRepository();
}
}
}
public class ContentRepository
{
// holds an object context and methods to retrieve and put data (EF or similar)
}
您必须使用 global.asax 中的 IOC 容器注册您的实例,例如 application_start,如下所示(使用 autofac 作为 IOC):
UnitOfWork worker = new UnitOfWork();
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterInstance(worker).SingleInstance();
var container = builder.Build();
...