Reputation: 784
I'm using EF for the first time, in a WPF application, using MVVM pattern. I read a lot of stuff but I couldn't end up with a solution. My problem is how to integrate EF in my app.
The most common way I found is build your own Repository + UnitOfWork. I don't like it. Basically because I already have DbContext and DbSet that can work as unit of work and repository, so why reinvent the wheel?
So I tried to use DbContext directly from view models like this
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>();
}
But I don't like to use DbContext directly from view models, so I built a service layer
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>();
}
But this way every action is atomic, so when I modify an entity I have to call SaveChanges() every time or loose changes, because DbContext is always disposed. So why not create a class-wide 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>());
}
}
Unfortunately, this way again doesn't work, because once a dbcontext is created, it is never disposed... So how about explicitly Open/Close the DbContext?
The question is: Where and how should I create/dispose the DbContext? The only thing I'm sure of is that I don't want to rebuild repository and unit of work, since they already exist as DbContext and DbSet...
Upvotes: 2
Views: 4785
Reputation: 21
I'm in the same position. I find that any persistent repository on the client side causes users not to see each others' changes.
Here's a good video explaining why EF is not the same as a repository
https://www.youtube.com/watch?v=rtXpYpZdOzM
Also I found an excellent end-to-end tutorial on WPF,MVVM & EF
http://www.software-architects.com/devblog/2010/09/10/MVVM-Tutorial-from-Start-to-Finish.
In this he exposes the data through a WCF data service and detaches them from the dbcontext straight away.
Hope it helps
Upvotes: 0