ASP.NET MVC,EntityFramework,DBContext,Repository在不同的Project中

teh*_*ner 11 c# asp.net asp.net-mvc entity-framework data-access-layer

我目前正在开发一个ASP.NET MVC 5项目,我正在努力改进项目的架构; 让人们在将来尽可能干净,轻松地工作.

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

但是,我现在正在考虑创建一个新的数据访问层项目,该项目将保存DbContext(或DbContexts,如果我决定使用多个DbContexts)以及数据访问层.这样做的最佳方法是什么?

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

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

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

1)什么是将DAL拉入单独项目的最佳方式

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

Aag*_*age 7

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

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

由于我无法通过最好的方式知道你的意思,我会给出我个人的偏好,这将适合典型的网络项目.

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

设置(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; } 
Run Code Online (Sandbox Code Playgroud)

使用包装器返回上下文:

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

}
Run Code Online (Sandbox Code Playgroud)

您可以像这样设置存储库:

接口:

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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

}
Run Code Online (Sandbox Code Playgroud)

域:

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

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

用户界面:

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

    return View(new UserViewModel());
}
Run Code Online (Sandbox Code Playgroud)

(这不是所有在Visual Studio中编写的,因此请原谅任何拼写错误.)

承认,在这段代码中可以有更多的抽象,但在这里写下整个解决方案是荒谬的.例如,您也可以使用工作单元模式,这与存储库模式非常相似.因此,请阅读此示例,而不是有关如何实现此设置的完整指南.事情可以比这个例子更清晰.

为了深入了解其中一些模式的实现,我建议您查看John Papa关于Plural Sight的单页应用程序.他在解释这些模式的好处以及如何实现它们方面做得非常出色.

  • 感谢这个@bump!我的意思是使用存储库模式值得吗?不是吗?如果是这样,您将如何继续在单独的项目中实现这一点。我有点困惑每个“层”是如何粘合在一起的,我还没有找到任何教程(针对 ASP.NET MVC)用代码示例来解释这一点。我得到了以下内容: WebApp.Model(它包含所有 POCO 类) WebApp.ViewModel(它包含视图模型,具有数据属性) WebApp.Controllers WebApp.Views 逻辑在哪里?即 GetAllUsers() id 喜欢有关 ASP.NET MVC 分层/关注点分离的教程 (2认同)