This is a migrated thread and some comments may be shown as answers.

How to create a Generic Repository

4 Answers 187 Views
LINQ (LINQ specific questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
LeandroHPA
Top achievements
Rank 2
LeandroHPA asked on 06 May 2013, 01:07 AM
Hi Folks!
First of all, thanks for all of you that are here reading. If you are not to help me, you are in the need of, so my post might help you ;)
If you are the one that knows how to make that. please, help me out!

I am migrating to Telerik ORM, and I am facing problem on implementing my Generic Repository that I have for Entity Framework.
Please find below my implementation of the IRepository class.

public class Repository<T> : IDisposable, IRepository<T> where T : class
    {
        protected readonly MaxxDB db = new MaxxDB();
 
        public virtual void Create(T item) {
            db.Set<T>().Add(item);
            db.SaveChanges();
        }
 
        public virtual void Remove(T item) {
            db.Set<T>().Remove(item);
            db.SaveChanges();
        }
 
        public virtual void Update(T item) {
            db.Entry(item).State = EntityState.Modified;
            db.SaveChanges();
        }
 
        public virtual T GetById(object id) {
            return db.Set<T>().Find(id);
        }
 
        public virtual IQueryable<T> All() {
            return db.Set<T>();
        }
 
        public void Dispose() {
            db.Dispose();
        }
 
    }

I am facing problems specifically on GetByID, since I could not find the "FIND" method on Open Access ORM, and in EF, this gets by the id(int) provided and recognizes the key property of the class.

Although, if any of you have a suggestion for a better repository implementation, please let me know!

Thanks a lot in advance!

4 Answers, 1 is accepted

Sort by
0
Accepted
Dimitar Tachev
Telerik team
answered on 08 May 2013, 03:55 PM
Hi Leandro,

 
Thank you for choosing Telerik OpenAccess ORM.

In general the recommended approach for getting an entity by some criteria (like its id) is using a lambda expression - please find the method below:

public T Get(Expression<Func<T, bool>> predicate)
{
    return this.Context.GetAll<T>().FirstOrDefault(predicate);
}

However if you don't like using this predicate you could also add a method for getting an entity directly by its id like the one below:
public T Get(object id)
{
    ObjectKey objectKey = new ObjectKey(typeof(T).Name, id);
    T entity = this.Context.GetObjectByKey(objectKey) as T;
 
    return entity;
}

For your convenience I also prepared a sample implementation of your generic repository using OpenAccess ORM: 
public class Repository<T> : IDisposable, IRepository<T>where T : class
{
    protected YouContextName Context
    {
        get;
        private set;
    }
  
    public Repository(YouContextName context)
    {
        this.Context = context;
    }
  
    public virtual IList<T> GetAll()
    {
        return this.Context.GetAll<T>().ToList();
    }
  
    public virtual T Get(Expression<Func<T, bool>> predicate)
    {
        return this.Context.GetAll<T>().FirstOrDefault(predicate);
    }
 
    public virtual T Get(object id)
    {
        ObjectKey objectKey = new ObjectKey(typeof(T).Name, id);
        T entity = this.Context.GetObjectByKey(objectKey) as T;
 
        return entity;
    }
  
    public virtual void Add(T order)
    {
        this.Context.Add(order);
    }
  
    public virtual void Remove(T order)
    {
        this.Context.Delete(order);
    }
 
    public virtual void SaveChanges()
    {
        this.Context.SaveChanges();
    }
  
    public void Dispose()
    {
        this.Context = null;
    }
}

Please bear in mind that the update method is missing because the updates are automatically tracked by the context and you just need to call the SaveChanges method to commit the changes in the database.

In order to have the possibility to pass the same context instance to all of your repositories I replaced the inline initialization of its context with an injection in the constructor which will reduce your database calls - the queries will be executed in the same transaction when you call the SaveChanges method.

Regarding the best generic repository implementation - it is depending on your scenario. For example if you are making some serialization and deserialization of your entities I suggest you to take a look at our Web API service generated by the Add OpenAccess Service wizard where you are getting a repository with attaching and detaching of its entities implemented out of the box.

You could find useful examples of different generic repositories in the end-to-end sample applications of our Samples Kit -  for Web API service examples you could take a look at the ASP.NET Web API with Kendo UI and ASP.NET Web API with WPF MVVM examples in the ASP.NET Web API section.

I hope this is applicable for you. Do not hesitate to contact us back if you need any further assistance.

Kind regards,
Dimitar Tachev
the Telerik team
Using Encrypted Connection Strings with Telerik OpenAccess ORM. Read our latest blog article >>
0
LeandroHPA
Top achievements
Rank 2
answered on 10 May 2013, 04:43 AM
Hi Dimitar!
Thank you SO MUCH!
I really appreciate your time for helping me.
I actually got a bit confused.

Would you please show me how would I build IRepository in this case?

Thanks a lot in advance!
Regards,
Leandro Andrade
0
Dimitar Tachev
Telerik team
answered on 13 May 2013, 04:11 PM
Hello Leandro,

 
In general the IRepository interface implemented by the generic repository class that I provided you could have only a part of its methods or all of them depending on your scenario.

For example it could look like the one below - having all of the repository methods extracted:

public interface IRepository<T> where T : class
{
    IList<T> GetAll();
    T Get(Expression<Func<T, bool>> predicate);
    T Get(object id);
    void Add(T entity);
    void Remove(T entity);
    void SaveChanges();
}

I believe that the easiest way for generating an interface from an existing class is using the Extract Interface Refactoring functionality of Visual Studio or other smart refactoring tool like Telerik JustCode - you could take a look at the articles describing this scenario.

If you choose using the Visual Studio functionality you could achieve that by right clicking on your class and selecting the Extract Interface operation from the Refactoring menu or using its CTRL+R, I shortcut.

I hope this helps. Do not hesitate to contact us back if you need any further assistance.

Greetings,
Dimitar Tachev
the Telerik team
OpenAccess Samples Kit boasts 50+ sample applications providing diverse real-life business solutions. Click to read more and see OpenAccess ORM in action.
0
LeandroHPA
Top achievements
Rank 2
answered on 14 May 2013, 03:38 AM
Hi Dimitar!
Thanks a bunch man! It sorted out my problems on this concern.

I am glad to being discovering and pactising with Kendo and also to have support from Telerik team. That means to me this company it's not only great on doing innovation, but beyond that, supporting us to come along, and keep it going and growing constantly.
P.S. I am a very potential future chargable member, but yet using for availing and learning purpose, and still got support on my problems.

Congratulations for being part of Telerik Team.

Leandro Andrade
Tags
LINQ (LINQ specific questions)
Asked by
LeandroHPA
Top achievements
Rank 2
Answers by
Dimitar Tachev
Telerik team
LeandroHPA
Top achievements
Rank 2
Share this question
or