Generic repository is a good idea if you will just use CRUD operations, (Create, Read, Update and Delete)
for me, i don't like much the to generate the database entities through DBML, i usually write entities and their mappings manually , here under some example of a project i am working on
first the model
public class Operator
{
public virtual string OperatorName { get; set; }
public virtual string LoginName { get; set; }
public virtual string Email { get; set; }
public virtual string PhoneNo { get; set; }
public virtual short Status { get; set; }
public virtual byte[] Password { get; set; }
}
UPDATE :
to make the repository independent of the provider you should define custom context which the repository will use
first define the interface
public interface IGenericContext
{
void Add<T>(T entity)
where T : class;
void Update<T>(T entity)
where T : class;
void Delete<T>(T entity)
where T : class;
IQueryable<T> GetIQueryable<T>()
where T : class;
}
here a sample of EF context that implements the IGenericContext interface
public class EFContext : DbContext, IGenericContext
{
public EFContext(string connectionName)
: base(connectionName)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.AddFromAssembly(this.GetType().Assembly);
base.OnModelCreating(modelBuilder);
}
public void Add<T>(T entity) where T : class
{
this.Set<T>().Add(entity);
this.SaveChanges();
}
public void Update<T>(T entity) where T : class
{
this.Set<T>().Attach(entity);
this.Entry(entity).State = EntityState.Modified;
this.SaveChanges();
}
public void Delete<T>(T entity) where T : class
{
this.Set<T>().Attach(entity);
this.Set<T>().Remove(entity);
this.SaveChanges();
}
public IQueryable<T> GetIQueryable<T>() where T : class
{
return this.Set<T>();
}
}
for EF, you will need to do the mappings yourself like below
public class OperatorMapping : EntityTypeConfiguration<Operator>
{
public OperatorMapping()
{
this.ToTable("Operators");
this.Property(t => t.OperatorName).IsRequired().HasColumnName("OperatorName");
this.HasKey(t => t.LoginName).Property(t => t.LoginName).HasColumnName("LoginName");
this.Property(t => t.Email).IsRequired().HasColumnName("Email");
this.Property(t => t.PhoneNo).HasColumnName("PhoneNo");
this.Property(t => t.Status).IsRequired().HasColumnName("Status");
this.Property(t => t.Password).IsRequired().HasColumnName("Password");
}
}
then a generic repository, this repository will use the IGenericContext instead of working on EF DBContext
public class Repository<TEntity>
where TEntity : class, new()
{
protected IGenericContext Context { get; set; }
public Repository(IGenericContext context)
{
Context = context;
}
public void Add(TEntity entity)
{
Context.Add(entity);
}
public void Update(TEntity entity)
{
Context.Update(entity);
}
public void Delete(TEntity entity)
{
Context.Delete(entity);
}
public List<TEntity> ToList()
{
return Context.GetIQueryable<TEntity>().ToList();
}
}
all you need to do is create the DBContext, pass it to the generic repository and do your operations
IGenericContext context = new EFContext("Infrastructure");
Repository<Operator> repository = new Repository<Operator>(context);
var operators = repository.ToList();
you can then implement another context that do the basic CRUD operations and still can use the same repository