1

I have an application in which the person who designed the application had used a dbml to manage db classes. But we have another database that we often need to connect to and we've been using ado.net normally to connect to it as we cannot use same dbml for it. However, I do not personally like using a LINQ database as the generated auto-code causes errors whenever we add a new table or property.

I've been trying to implement a repository pattern with self-declared classes to map to each table but to manage operations on each table, we need a separate repository for each entity. I'm not sure if I'm on the right path using this pattern but if I'm not using EF in this case, can we have a generic repository to represent the general operations or just create separate repository for each entity that we create?

Also, for generic repository, I would appreciate if I can get some example or pointers to it.

Sorry if I sound redundant. Thanks in advance!

pulkitgulati
  • 41
  • 2
  • 9
  • I would create a generic repository. If some entities do not requried more than base CRUD, so creating sepratte class for each is in my opinion pointless. And - reppository is pattern is OK without EF - Database is just one of ways to persist data. You could also create repo that operates on XML, JSON on something else. –  Nov 03 '14 at 07:22
  • yeah that's what my initial thought was... but I've been struggling to get going by creating the right class to define those operations. All examples that I found were using EF only to implement repository pattern. Can you please provide an example for implementing Generic Repository that I can replicate and customize accordingly. – pulkitgulati Nov 03 '14 at 07:31
  • Generic Repository is an anti pattern and it really works only if you're just serializing your objects. In your specific case, I'd use EF Code First directly, it does exactly what you want. If you really hate EF, try NHibernate or a micro-ORM . – MikeSW Nov 04 '14 at 18:42

1 Answers1

0

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

mfarouk
  • 644
  • 5
  • 14
  • 1
    I thought the OP wants example that is not based on `EF` – Leron Nov 03 '14 at 08:30
  • By exposing IQueryable you'll rely on EF specific behaviors that may or may not be available with another provider. You could use an `IDbSet` instead of a custom repository. – Guillaume Nov 03 '14 at 08:35
  • i will amend the answer to make the repository independent in the provider – mfarouk Nov 03 '14 at 08:49
  • Thanks for taking out time to explain. I'm looking for a solution not based on EF. I've been struggling to find it. – pulkitgulati Nov 03 '14 at 10:25
  • actually this is not based on EF, EF is used in the answer as an example only, you just need to do your custom IGenericContext, and implement Add, Update, Remove and AsQueryable functions, then pass it to your repository – mfarouk Nov 03 '14 at 10:51
  • Thanks for the answer mfarouk. Dou you have a template that is implemented without EF? – Fuat Apr 13 '17 at 13:59
  • template in the answer should fit in scenarios without EF, all you need to do is to re-implement IGenericContext, and to speed development for CRUD operations, you can use Dapper.Net micro ORM – mfarouk Apr 21 '17 at 20:48