12

我目前正在开发一个ASP.NET MVC 5项目,并且正在尝试完善该项目的体系结构;尽可能让人们在未来的工作中保持干净和容易。

对于初学者,我已将我的EntityFramework模型(包括 IdentityUser 和 AccountViewModel)移动到同一解决方案中的类库项目中。这是目前主要的 MVC 项目引用的。

但是,我现在正在考虑创建一个新的数据访问层项目,该项目将保存 DbContext(或 DbContext,如果我决定使用多个 DbContext)以及数据访问层。继续执行此操作的最佳方法是什么?

此 DAL 项目将引用 Model 项目,而主 MVC 项目将仅引用 DAL 项目。

看完这篇文章!我想知道在使用 EntityFramework 时存储库模式是否确实已经过时。

所以我的两个主要问题是:

1) 将 DAL 提取到单独项目中的最佳方法是什么

2) 使用 EF 访问数据库内容的最佳方式是什么

4

1 回答 1

8

你的问题很广泛。例如,“使用 EF 访问数据库内容的最佳方式”是什么意思?性能方面的最佳方式?

我将尝试通过给出一个我更喜欢的选项来回答(我主要使用一些变体),它使用存储库模式。如果您将 EF 集直接用作存储库,您可能会争辩说您不需要存储库模式,但我喜欢将它们包装在我自己的一个中。

由于我不知道您所说的最佳方式是什么意思,我将给出我个人的偏好,这将适合典型的 Web 项目。

我不会发布所有代码以使其完全正常运行,但您应该清楚地了解发生了什么。

设置(4个项目):

UI ----------> Domain.Logic (w. Domain.Models) -----------------> 数据(保存 EF 上下文)。

数据:

public partial class EFContextContainer : DbContext 
enter code here
public EFContextContainer ()
        : base("name=EFContextContainer")
    {
    }

public DbSet<IdentityUser> IdentityUsers { get;set; } 

使用返回上下文的包装器:

public static class Database
{
    public static EFContextContainerGetContext()
    {
        return new EFContextContainer();
    }

}

你可以有一个这样的存储库设置:

界面:

public interface IRepository<T> where T : class
{
    IQueryable<T> GetAll();
    T GetById(Guid id);
    void Add(T entity);
    void Update(T entity);
    void Delete(T entity);
    void Delete(Guid id);
}

实现(为简洁起见,仅实现了 Add(T entity)):

public class EFRepository<T> : IRepository<T>, IDisposable where T : class
{
    public EFRepository(DbContext dbContext)
    {
        if (dbContext == null)
            throw new ArgumentNullException("dbContext");
        DbContext = dbContext;
        DbSet = DbContext.Set<T>();

    }

    protected DbContext DbContext { get; set; }

    protected DbSet<T> DbSet { get; set; }

    public virtual void Add(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State != EntityState.Detached)
        {
            dbEntityEntry.State = EntityState.Added;
        }
        else
        {
            DbSet.Add(entity);
        }
    }

public void Dispose()
    {
        DbContext.Dispose();
    }

}

领域:

Domain.Logic(IdentityUserManager 将是 Domain.Models 中的一个类):

public class IdentityUserManager
{
    public void Add(IdentityUser idUser)
    {
        using(var idUserRepository = new EFRepository<IdentityUser>(Database.GetContext())
        {
            idUserRepository.Add(idUser);
        }
    }
}

用户界面:

[HttpPost]
public ActionResult Post(UserViewModel model)
{
    UserIdentity user = MapUser(model);
    var userManager = new IdentityUserManager();
    userManager.Add(user);

    return View(new UserViewModel());
}

(这不是全部在 Visual Studio 中编写的,所以请原谅任何拼写错误。)

承认,这段代码中可能有更多的抽象,但在这里写下整个解决方案是荒谬的。例如,您也可以使用工作单元模式,它与存储库模式配合得很好。因此,请阅读此示例,而不是有关如何实施此设置的完整指南。事情可以设置得比这个例子干净得多。

为了深入了解其中一些模式的实现,我强烈建议您查看John Papa 在 Plural Sight 上的Single Page Apps课程。他出色地解释了这些模式的好处以及如何实现它们。

于 2013-10-29T10:10:16.400 回答