asp.net mvc数据逻辑结构

时间:2014-02-05 23:09:46

标签: c# asp.net asp.net-mvc linq asp.net-mvc-4

所以我有一堆实体模型。

许多控制器和视图以及控制器经常会执行linq查询并将其提供给视图。

但是,假设我有一个模型用户

我有一个linq查询来获取所有活跃用户

将它放在控制器中可能没问题,如果它完成一次,但我想重复它,我想知道在哪里放置模型特定查询的正确位置。

理想情况下,控制器会显示Users.getActiveUsers()或类似内容。

2 个答案:

答案 0 :(得分:2)

您应该查看存储库模式。

存储库模式允许您抽象此数据库逻辑并减少公共数据调用的冗余。由于您经常编写LINQ查询,为什么不将它们放入一个公共类?

public class UserRepository 
{
     private readonly _dbContext MyDbContext;

     public IEnumberable<User> getActiveUsers() 
     {
          // whatever you do to find the active users
          return _dbContext.Where(user => user.Active == true);
     }
}

现在您可以将此存储库注入您的控制器。

public class HomeController : Controller
{
     private readonly UserRepository _userRepo;

     public HomeController()
     {
         _userRepo = new UserRepository();
     }

     public ActionResult Index()
     {
          var activeUsers = _userRepo.getActiveUsers();

          return View(activeUsers);
     }
}

上述实现将解决您的问题,但它确实将您的控制器与您的存储库紧密耦合。解耦它们的解决方案是使用UserRepository的接口,然后使用依赖注入(使用Ninject,Unity,AutoFaq或其他)来解析接口的类型。

答案 1 :(得分:2)

我建议将数据访问逻辑移动到单独的类(repositories),这些类将充当实体的内存集合并隐藏所有数据访问逻辑。例如。如果您有实体User,则可以创建存储库,该存储库将封装与用户相关的所有linq查询:

public class UserRepository : IUserRepository
{
    private YourDbContext _db;     

    public UserRepository(YourDbContext db)
    {
        _db = db;
    }

    public User GetById(int id)
    {
        return _db.Users.Find(id);
    }

    public IEnumerable<User> GetAll()
    {
        return _db.Users.AsEnumerable();
    }

    public IEnumerable<User> GetUsersByRole(string role)
    {
        return _db.Users.Where(u => u.Role == role).AsEnumerable();
    }
}

这将把所有数据访问代码保存在一个地方,而不会重复。当您添加另一个存储库时,您会发现一些重复的逻辑(例如,通过id获取实体,或获取所有实体),这些逻辑可以移动到基础generic repository类。

我还建议依赖控制器中的存储库接口:

public interface IUserRepository
{
    User GetById(int id);
    IEnumerable<User> GetAll();
    IEnumerable<User> GetUsersByRole(string role);
}

这将使控制器的单元测试非常容易(模拟存储库和注入模拟):

public class UserController : Controller
{
    private readonly IUserRepository _userRepository;

    public UserController(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public ActionResult Index()
    {
        // Note: usually you should not use entities in view 
        // create appropriate view models and map entities to them
        var model = _userRepository.GetAll();
        return View(model);
    }
}