繁体   English   中英

ASP.NET MVC数据逻辑结构

[英]asp.net mvc data logic structure

所以我有一堆实体模型。

许多控制器和视图,并且控制器经常去执行linq查询并将其提供给视图。

但是可以说我有一个模型用户

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

如果一次完成,将其放入控制器中可能会很好,但是我想重复一遍,我想知道将特定于模型的查询放在哪里。

理想情况下,控制器将显示Users.getActiveUsers()或类似名称。

您应该查看存储库模式。

使用存储库模式,您可以抽象化此数据库逻辑并减少常见数据调用的冗余。 既然您经常制定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或其他方式)来解析该接口的类型。

我建议将数据访问逻辑移到单独的类( 存储库 ),这些类将充当实体的内存中集合并隐藏所有数据访问逻辑。 例如,如果您有实体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获取实体,或获取所有实体),这些逻辑可以移动到基本通用存储库类中。

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

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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM