【发布时间】:2016-02-09 20:30:28
【问题描述】:
我目前正在使用 .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 中都取得了成功。
【问题讨论】:
-
不要持久化 DbContexts。曾经。这不是它们的设计方式。在狭窄范围内创建和处置它们(最好使用
using语句)。与它执行的操作的成本相比,创建 DbContext 的成本是微不足道的。不要害怕更新 DbContexts 并经常处理它们。它们很轻,这就是它们的用途。 -
如果你想在一个中心位置“管理”数据库上下文,就会想到工作单元模式
标签: c# .net wpf entity-framework