我该如何调用用MVC编写的模型类?

时间:2013-08-18 12:15:27

标签: asp.net-mvc

您好我有用MVC编写的模型类。我使用的是Ef数据库第一种方法。在模型类中,我有一些处理数据库的查询。我有以下问题:

1)在Model中使用与数据库相关的查询并在控制器或视图中调用它是正确的方法吗?

2)如果是,我应该在哪里打电话给这个型号?在Controller或视图中??

3)我该如何称呼这个模型?比方说,我在模型中有一个名为class1.cs的类。我应该调用这个模型吗?

3 个答案:

答案 0 :(得分:1)

您的模型包含用于定义项目中不同对象的类。这包括具有基本信息的属性以及对此对象执行操作的方法。

1) 你真的需要查询吗?为什么不使用实体框架为您完成?为您的域类创建映射(通过注释或流畅的api)并使用DbContext检索并保存存储在数据库中的数据

2) 理想情况下,人们创建注入控制器的存储库(依赖注入)。例如,这些存储库可以包含GetPersonById(int id)之类的内容。在这种方法中,有两件事:

  1. 对域对象执行操作
  2. 将其保存到DbContext
  3. 例如:

    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 :(得分:0)

您可以使用某种工作单元模式,您可以使用控制容器(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,application_start中注册您的实例与IOC容器,例如,类似这样(使用autofac作为IOC):

UnitOfWork worker = new UnitOfWork();
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());

builder.RegisterInstance(worker).SingleInstance();
var container = builder.Build();

...

答案 2 :(得分:0)

1)在Model中使用与数据库相关的查询并在控制器或视图中调用它是正确的方法吗?

我建议不要直接访问模型类中的数据库,因为你必须记住MVC严格来说是表示层模式。如果确实将数据库访问逻辑放在模型类中,那么您将无法让任何其他客户端使用此功能,例如Web服务。相反,它具有将您的ASP.NET MVC项目之外定义的业务对象转换为ASP.NET MVC模型类的逻辑。

这就是n层架构的强大之处,如果你创建一个业务和数据访问层,那么我就可以编写一个ASP.NET MVC前端,WebForms前端,WPF前端,WinForms前端和所有这些都可以使用相同的服务访问数据。通过将逻辑放入ASP.NET MVC模型类,您可以有效地强制任何其他客户端在其类中再次复制该逻辑。