我已经烦恼了几天,仍然无法决定哪种方法是正确的。
这个问题特别针对 WPF
,因为与 Web 应用程序不同,许多在线文章和帖子推荐采用每个 view-model
对应一个 context
的方法,而不是每个 request
对应一个 context
。
我有一个使用 Entity-Framework DB first
模型的 WPF MVVM
应用程序。
下面是我应用程序中使用的两个模型的示例(由 EF
设计器创建):
public partial class User
{
public User()
{
this.Role = new HashSet<Role>();
}
public string ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Role> Role { get; set; }
}
public class Role
{
public Role()
{
this.User = new HashSet<User>();
}
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<User> User { get; set; }
}
我已经将如何处理这个问题的选择缩小到以下几点:
1) 创建一个 DataAccess
类,在每次方法调用时创建和释放 DbContext
:
public class Dal
{
public User GetUserById(object userId)
{
using (var db = new DbEntities())
{
return db.User.Find(userId);
db.SaveChanges();
}
}
public void RemoveUser(User userToRemove)
{
using (var db = new DbEntities())
{
db.User.Remove(userToRemove);
db.SaveChanges();
}
}
}
我可以在我的ViewModel
中使用它,如下所示:
public class UserManagerViewModel : ObservableObject
{
private readonly Dal dal = new Dal();
// models...
//commands...
}
2) 类似于方法1,但是不使用 Using
语句:
public class Dal : IDisposable
{
private readonly DbEntities db = new DbEntities();
public User GetUserById(object userId)
{
return db.User.Find(userId);
db.SaveChanges();
}
public void RemoveUser(User userToRemove)
{
db.User.Remove(userToRemove);
db.SaveChanges();
}
public void Dispose()
{
db.SaveChanges();
}
}
ViewModel
内部使用方法与上述相同。
3) 为每个 entity
创建一个 repository
。看起来与上面的选项相同(也存在 using
的困扰),然而每个 repository 只包含与其 entity
相关的方法。据我所知,在我的 ViewModel
中使用方式与以上相同。
4) 创建一个 Unit-Of-Work
类,将根据需要传递适当的 Repository
:
public class UnitOfWork : IDisposable
{
private DbEntities db = new DbEntities();
private IUserRepository userRepository;
public IUserRepository UserRepository
{
get
{
return userRepository ?? new UsersRepository(db);
}
}
public void Save()
{
db.SaveChanges();
}
public void Dispose()
{
db.Dispose();
}
}
然后在我的ViewModel
中使用它,如下所示:
public class UserManagerViewModel : ObservableObject
{
private readonly UnitOfWork unit = new UnitOfWork();
// models...
//commands...
}
在数据并发、更好的抽象和分层以及总体性能方面,上述方法中哪种(如果有)是首选?
编辑 - 在这篇文章中发现了以下段落:
在使用 Windows Presentation Foundation (WPF) 或 Windows Forms 时,每个表单都应该使用一个上下文实例。这样可以使用上下文提供的更改跟踪功能。
然而,这引出了一个问题,我应该在我的视图模型中创建一个 DbContext
对象,还是最好有一个类似于我的 DAL
类的实用程序类并引用它。