[英]ASP.NET MVC 5 application - Repository pattern without Entity Framework
[英]ASP.Net MVC & Entity Framework project architecture WITHOUT repository pattern
我正在使用ASP.NET MVC和Entity Framework开始一个新的小项目。 (SQL Server - 大约20个DB表)在过去的项目中我使用过Linq2SQL,但它似乎已经过时了。
我已经阅读了很多关于使用EF存储库模式的帖子(优点和缺点),对我而言,没有存储库模式的代码似乎更好/更简单。
我创建了以下项目架构:
namespace MySite.Models
{
public class User
{
public Int32 ID { get; set; }
public String Email { get; set; }
public String Password { get; set; }
public String Name { get; set; }
public Int32 Gender { get; set; }
}
}
namespace MySite.DAL
{
public class Users
{
public static IEnumerable<User> GetUsers()
{
using (var context = new DatingSiteContext())
{
return context.Users.ToList();
}
}
public static User GetUserByID(int id)
{
using (var context = new DatingSiteContext())
{
return context.Users.Find(id);
}
}
}
namespace MySite.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
var users = DAL.Users.GetUsers();
return View(users);
}
}
}
谢谢。
编辑:
GetUsers()和GetUserByID()中的代码只是例如,我理解从db返回所有记录的错误做法(缺少分页或过滤器)
你实际上只创建了一个存储库,你只称它为“数据访问层”,在我看来,这不是一个好名字,因为Entity Framework是数据访问层。 在这种情况下,存储库是数据访问层(实体框架)之上的抽象。
在每次调用DAL时创建一个新的DbContext是错误的吗? 任何表现命中?
不,这很好,但是当你在DbContext
一个实例中获取一个实体时,它可能会造成麻烦,并尝试在另一个实例中更新它。
你会在一个新项目中使用Linq2SQL吗?
不,微软提出实体框架作为L2SQL的继承者,并且它的积极开发已经停止。
使用EF的任何其他推荐结构? 例子? :)
您使用的方法,特定的存储库,将导致大量冗余代码。 您可以创建实现接口的通用存储库:
public interface IRepository<TEntity>
where TEntity : class, new()
{
IEnumerable<TEntity> GetAll();
TEntity GetById(int id);
IQueryable<TEntity> Table { get; }
}
并执行此:
public EfRepository<TEntity> : IRepository<TEntity>
where TEntity : class, new()
{
private readonly DatingSiteContext _context;
public EfRepository()
{
_context = new DatingSiteContext();
}
private IDbSet<TEntity> Entities
{
get
{
return _context.Set<TEntity>();
}
}
public IEnumerable<TEntity> GetAll()
{
return Entities.ToList();
}
public TEntity GetById(int id)
{
return Entities.Find(id);
}
public IQueryable<TEntity> Table
{
get { return Entities; }
}
}
您可以在控制器中使用此存储库,如下所示:
public class HomeController : Controller
{
private readonly IRepository<User> _userRepository;
public HomeController()
{
_userRepository = new EfRepository<User>();
}
public ActionResult Index()
{
var users = _userRepository.GetAll();
var inactiveUsers = _userRepository.Table.Where(u => !u.Active).ToList();
}
}
此通用存储库允许您创建模拟存储库:
public class FakeUserRepository : IRepository<User>
{
// ...
}
IRepository<>
字段。
然而, IQueryable<>
属性具有很大的灵活性,允许延迟执行。
我不是说这是最好的方法,只是我经常在项目中使用的方法。 我不得不说我通常在控制器和存储库之间编写一个业务(服务)层。 我保留了我的业务逻辑和复杂的Linq查询(及其执行)。 我还使用一个IoC容器来处理我的对象的生命周期(例如DbContext
和服务的实例)。 有关详细信息,请参阅此问题 。
我的想法
有什么缺点:
在每次调用时创建一个新的DbContext是错误的吗?
其他模式
你会使用Linqtosql吗?
我会重新思考你是如何实现GetUsers()
。 您正在调用ToList()
,这将导致基础表中的所有行返回并存储在内存中。 如果表格变得足够大,您将遇到性能问题。 最好返回一个IQueryable<User>
,让你的方法return context.Users
。
当然,在执行IQueryable<>
,您将遇到上下文已被处理的问题,因此您需要以不同的方式处理上下文的生命周期。
如果项目足够小,那么您可以在Controller级别存储Context的实例,并在处理控制器时将其丢弃。 如果这样做,请确保在视图中不执行任何会导致执行其他查询的操作(例如,如果存在,则访问User
的集合),否则将导致错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.