How to use Repository pattern using Database first approach in entity framework.I got some idea while going through resources available on internet but for real time applications I am not sure how to implement repository pattern on the auto generated classes from the DB first approach.
I have already gone through some links in SO but I did not get any clear idea.I am new to this one. Thanks in Advance.
Entity Framework already implements a repository pattern. DbContext is your UoW (Unit of Work) and each DbSet is the repository. Implementing another layer on top of this is not only redundant, but makes maintenance harder. People follow patterns without realizing the purpose of the pattern.
The Database First Approach provides an alternative to the Code First and Model First approaches to the Entity Data Model. It creates model codes (classes, properties, DbContext etc.) from the database in the project and those classes become the link between the database and controller.
The code generation tool will only modify the classes that are mapped to the XML files. You have a couple of options:
1) You can extend the mapped classes by using partial classes. Partial classes will not be modified by the automated tool when updating the code with the tool.
2) You can also handle data annotations and entity configuration to a Configuration file, just be cautious because in some cases they may conflict. Down below a snippet:
public class YourClassConfiguration : EntityTypeConfiguration<YourClass>
{
public YourClassConfiguration()
{
ToTable("YourTable");
HasKey(e => e.Property1);
Property(e => e.Property1).HasColumnName("MyName").HasMaxLength(30);
}
}
I was working with this approach and honestly, I would suggest you moving your implementation to a Code First approach as I did. In my personal opinion, it's a pain maintaining and fixing problems when the designer decides to create duplicate keys or not updating properly the XML file as it happen to me more than once. The good news is that you can avoid migrations and some of the features used by Code First and preserving the DB structure as is. Everything can be configured. I can tell you more if you are interested.
Anyhow, I am also attaching you a simple code snippet of a GenericRepository pattern that you may find useful. I will also strongly suggest using dependecy Injection in your implementation (Required by the GenericRepository pattern to resolve dependencies). I would recommend Autofac. It's very stable and has great support.
public class EntityRepository<T> : IRepository<T>, IDisposable where T
: class, IEntity
{
private readonly DbSet<T> dbset;
private readonly DbContext _context;
private readonly bool _lazyLoadingEnabled = true;
public EntityRepository(DbContext context, bool lazyLoadingEnabledEnabled)
: this(context)
{
_lazyLoadingEnabled = lazyLoadingEnabledEnabled;
}
public EntityRepository(DbContext context)
{
_context = context;
_context.Configuration.LazyLoadingEnabled = _lazyLoadingEnabled;
dbset = context.Set<T>();
}
public void Add(T entity)
{
dbset.Add(entity);
_context.SaveChanges();
}
public void Update(T entity)
{
var originalValues = FindOne(x => x.Id == entity.Id);
_context.Entry(originalValues).CurrentValues.SetValues(entity);
_context.SaveChanges();
}
public void Remove(T entity)
{
dbset.Remove(entity);
_context.SaveChanges();
}
public List<T> Find(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
return dbset.Where(predicate).ToList();
}
public T FindOne(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
return dbset.FirstOrDefault(predicate);
}
public List<T> FindAll()
{
return dbset.ToList();
}
}
The interface is quite simple:
public interface IRepository<T>
where T : class, IEntity
{
void Add(T entity);
void Update(T entity);
void Remove(T entity);
T FindOne(Expression<Func<T, bool>> predicate);
List<T> Find(Expression<Func<T, bool>> predicate);
List<T> FindAll();
}
Apply the interface to the partial classes you created to extend the database first classes and you will be able to query those entities within the repository. You can also add Properties to the repository interface to have those properties visible and add common functionality of searching using common properties such as Id, name and so on if applicable.
I hope it helps,
Carlos
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With