简体   繁体   English

在WPF应用程序中管理DbContext

[英]Managing DbContext in WPF Application

I am currently working on a WPF application using .NET 4.6. 我目前正在使用.NET 4.6开发WPF应用程序。 We are using the Entity Framework for Persistence and Database interaction with SQL Server. 我们正在使用实体框架与SQL Server进行持久性和数据库交互。 When I joined the project all the database interaction was being done in the code behind like the following. 当我加入该项目时,所有数据库交互都在下面的代码中完成,如下所示。 (Yes I realize this is bad practice) (是的,我知道这是不好的做法)

IList<User> users;
using (AppDbContext db = new AppDbContext())
{
    users = db.Users.Where(x => x.Active == true).ToList();
}

// do code to update UI

I basically said this is bad practice, we need to separate out the business logic and queries from the presentation layer. 我基本上说这是一种不好的做法,我们需要从表示层中分离出业务逻辑和查询。 I thought the Repository pattern might be a nice place to start but I have doubts about how the DbContext will be managed. 我以为存储库模式可能是一个不错的起点,但是我对如何管理DbContext表示怀疑。

Example Repository Interface 仓库接口示例

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

And the implementation 并执行

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

The issue now is when there are multiple windows open there are multiple contexts open and long running contexts. 现在的问题是,当有多个窗口打开时,有多个打开的上下文和长时间运行的上下文。 One of the ideas floating around right now is to use a single context for the entire application, since it is a single user desktop application, however that doesn't seem like the best idea. 目前浮现的想法之一是对整个应用程序使用单个上下文,因为它是单个用户桌面应用程序,但是这似乎不是最好的想法。 Also the dbContexts need to be disposed off when the windows are closing, etc. 另外,在关闭窗口等情况下,还需要处理dbContext。

I've read about the idea of using a DbContext per request in ASP.NET. 我已经了解了在ASP.NET中每个请求使用DbContext的想法。 Maybe one could be used per Window? 也许每个窗口可以使用一个?

I'm just wondering if the repository pattern is the best way for WPF applications? 我只是想知道存储库模式是否是WPF应用程序的最佳方法? I've seen many people have success with it in ASP.NET. 我已经看到许多人在ASP.NET中成功使用它。

You could create a sort of unitofwork on top of your repositories, and contructor inject the dbcontext into the repositories 您可以在存储库顶部创建某种工作单元,然后构造器将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;
    }

}

Then you just call 那你就打电话

unitOfWork.UserService.GetUsers();

... This gives one more layer of abstraction, you still need to handle the single instance of unitofwork, but that can be handled nicely with some DI magic :) ...这提供了更多的抽象层,您仍然需要处理unitofwork的单个实例,但是可以使用一些DI魔术很好地处理它:)

Note: i wrote this from the android app! 注意:我是从android应用程序编写的! (Coding c# on a phone, does not rock!) (在手机上编码c#不会晃动!)

It really depends on how you use your DbContext. 这实际上取决于您如何使用DbContext。 If you are reading some data could be changed by some other application, I would suggest use disposable DbContext every time. 如果您正在读取某些数据,而其他应用程序可能会更改这些数据,则建议每次都使用一次性DbContext。 If you are sure your application is the only one to touch the database, then keep a single DbContext in your repository and use a singleton repository across the entire application. 如果您确定您的应用程序是唯一接触数据库的应用程序,则在存储库中保留一个DbContext并在整个应用程序中使用一个单例存储库。

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

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