在 WPF 应用程序中管理 DbContext

本文关键字:管理 DbContext 应用程序 WPF | 更新日期: 2023-09-27 18:33:59

我目前正在使用.NET 4.6开发WPF应用程序。我们使用实体框架与 SQL Server 进行持久性和数据库交互。当我加入该项目时,所有数据库交互都是在代码隐藏中完成的,如下所示。(是的,我意识到这是不好的做法(

IList<User> users;
using (AppDbContext db = new AppDbContext())
{
    users = db.Users.Where(x => x.Active == true).ToList();
}
// do code to update UI

我基本上说这是不好的做法,我们需要将业务逻辑和查询与表示层分开。我认为存储库模式可能是一个很好的起点,但我对如何管理 DbContext 有疑问。

存储库接口示例

public interface IUserService : IDisposable
{
    IList<applicationuser> GetUsers();
    IList<AllApplicationUser> GetActiveUsers();
    AllApplicationUser GetUserView(long id);
    applicationuser GetUser(long id);
    void CreateUser(applicationuser user);
    void UpdateUser(applicationuser user);
    void DeleteUser(long id);
    void Save();
    applicationuser Authenticate(string username, string password);
}

和实施

class UserService : IUserService
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        private readonly OMEGAEntities _db;
        private bool _disposed = false;
        public UserService()
        {
            _db = new OMEGAEntities();
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    _db.Dispose();
                }
            }
            _disposed = true;
        }
        public IList<applicationuser> GetUsers()
        {
            // fetch only active users that do not have the role SuperAdmin
            return _db.applicationusers.Where(u => u.roleid != 1 && u.activeflag == true).ToList();
        }
        public IList<AllApplicationUser> GetActiveUsers()
        {
            return _db.AllApplicationUsers.Where(u => u.activeflag == true && u.roleid != 1).ToList();
        }
        public AllApplicationUser GetUserView(long id)
        {
            return _db.AllApplicationUsers.Single(x => x.id == id);
        }
        public applicationuser GetUser(long id)
        {
            return _db.applicationusers.Find(id);
        }
        public void CreateUser(applicationuser user)
        {
            _db.applicationusers.Add(user);
        }
        public void UpdateUser(applicationuser user)
        {
            _db.Entry(user).State = EntityState.Modified;
        }
        public void DeleteUser(long id)
        {
            var user = _db.applicationusers.Find(id);
            _db.applicationusers.Remove(user);
        }
        public void Save()
        {
            _db.SaveChanges();
        }
        public applicationuser Authenticate(string username, string password)
        {
            applicationuser user =
                _db.applicationusers.SingleOrDefault(u => u.loginid.ToLower().Equals(username.ToLower()));
            if (user != null)
            {
                if (Common.Utils.DecryptData(user.password).Equals(password))
                {
                    return user;
                }          
            }
            return null;
        }
    }

现在的问题是,当打开多个窗口时,会打开多个上下文并长时间运行上下文。现在流传的一个想法是对整个应用程序使用单个上下文,因为它是一个单用户桌面应用程序,但这似乎不是最好的主意。此外,当窗口关闭时,dbContexts需要被释放出来,等等。

我已经读过关于在 ASP.NET 中为每个请求使用 DbContext 的想法。也许每个窗口可以使用一个?

我只是想知道存储库模式是否是 WPF 应用程序的最佳方式?我看到很多人在 ASP.NET 取得了成功。

在 WPF 应用程序中管理 DbContext

您可以在存储库之上创建一种工作单元,然后构造器将数据库上下文注入存储库

public class UnitOfWork : IUnitOfWork
{
    private IUserService userService;
    private omegaentities dbcontext;
    public UnitOfWork ()
    {
    dbcontext = new Omegaentities ();
    }
    public IUserService UserService {
    get {
             If (userService == null)
             { userService = new UserService(dbcontext);}
    Return userService;
    }
}

然后你只需打电话

unitOfWork.UserService.GetUsers();

。这提供了更多的抽象层,您仍然需要处理 unitofwork 的单个实例,但这可以通过一些 DI 魔术:)很好地处理

注意:我是从安卓应用程序写的!(在手机上编写 c# 代码,不会摇滚!

这实际上取决于您如何使用 DbContext。 如果您正在读取某些数据可能会被其他应用程序更改,我建议每次都使用一次性 DbContext。 如果您确定您的应用程序是唯一接触数据库的应用程序,请在存储库中保留单个 DbContext,并在整个应用程序中使用单一实例存储库。