实体框架 - WPF/MVVM应用程序中的基础结构
我在使用MVVM模式的WPF应用程序中首次使用EF。我读了很多东西,但我不能以解决方案结束。我的问题是如何将EF整合到我的应用程序中。实体框架 - WPF/MVVM应用程序中的基础结构
我发现的最常见的方法是构建您自己的Repository + UnitOfWork。我不喜欢它。基本上,因为我已经有了可以作为工作单元和存储库的DbContext和DbSet,那么为什么要重新发明*?
于是,我就直接从视图模型使用的DbContext这样
public class BookCollectionViewModel : ViewModelBase
{
public void LoadCollection()
{
Books.clear();
var books = new List<Book>();
using(var ctx = new DbContext())
{
books = ctx.DbSet<Book>().ToList();
}
books.Foreach(b => Books.Add(b));
}
ObservableCollection<Book> Books { get; } = new ObservableCollection<Book>();
}
但我不喜欢直接从视图模型使用的DbContext,所以我建立了一个服务层
public class DbServices
{
public TReturn Execute<TEntity>(Func<IDbSet<TEntity>, TReturn> func)
{
TReturn retVal = default(TReturn);
using(var ctx = new DbContext())
{
retVal = func(ctx.DbSet<TEntity>());
}
return retVal;
}
}
public class BookCollectionViewModel : ViewModelBase
{
private DbServices mDbServices = new DbServices();
public void LoadCollection()
{
Books.clear();
var books = mDbServices.Execute<Book>((dbSet) => return dbSet.ToList());
books.Foreach(b => Books.Add(b))
}
ObservableCollection<Book> Books { get; } = new ObservableCollection<Book>();
}
但是这样每一个动作都是原子的,所以当我修改一个实体时,我必须每次都调用SaveChanges()或者松散的修改,因为DbContext总是处置掉。那么为什么不创建一个类的DbContext呢?
public class DbServices
{
private Lazy<> mContext;
public DbServices()
{
mContext = new Lazy<TContext>(() => {return new DbContext();});
}
public TContext Context { get { return context.Value; } }
public TReturn Execute<TEntity>(Func<IDbSet<TEntity>, TReturn> func)
{
return func(Context.DbSet<TEntity>());
}
}
不幸的是,这种方式又是不行的,因为一旦被创建的DbContext,这是从来没有布置......因此,如何明确地打开/关闭的DbContext?
问题是:我应该在哪里以及如何创建/处理DbContext?我唯一能确定的是我不想重建版本库和工作单元,因为它们已经存在为DbContext和DbSet ...
我处于相同的位置。我发现客户端上的任何持久存储库都会导致用户看不到对方的更改。
这里有一个很好的视频,解释为什么EF是不一样的仓库
https://www.youtube.com/watch?v=rtXpYpZdOzM
另外我发现一个优秀的终端到年底教程WPF,MVVM & EF
http://www.software-architects.com/devblog/2010/09/10/MVVM-Tutorial-from-Start-to-Finish。
在此,他通过WCF数据服务公开数据,并立即将它们从dbcontext中分离出来。
希望它有帮助
要回答你的问题,你不能让'DbServices'实现'IDisposable'吗? - 但是,我认为你在这里挖了一个洞,你正在避免工作单元模式,但是你在这里基本上是一个存储库。屈服于这种模式,成为我们中的一个,我们中的一个,我们中的一个**。 –
感谢您的回复Mike。是的,正如我所说我可以实现IDisposable,并根据需要显式打开/关闭dbcontext。但在这一点上,我不再需要DbServices类,并直接使用DbContext ...我一定会使用_the pattern_,我不会(重新)写它,并直接使用DbContext/DbSet ... – Marco