0

I have been assigned a new project and I have decided to give EF a go.In this project all I do is getting data there is no persistence.I have to implement some caching and that's it.

Reading about Repository patterns I have found tons of code samples etc... they seem all wrong to me.They implement a one to one Entity to Repository.

In my project I just need reading data not saving etc... just reading.I have 100s entities I cannot create 100s repository seems all wrong.

I have decided to start simple and I all need is this:

public interface IRepository : IDisposable
{
    IEnumerable<T> GetAll<T>() where T : class;
    IEnumerable<T> Find<T>(Expression<Func<T, bool>> predicate) where T : class;
    T GetOne<T>(Expression<Func<T, bool>> predicate) where T : class;
}

public class Repository : IRepository
{
    public IEnumerable<T> GetAll<T>() where T : class
    {
        return ???.ToArray();
    }

    public IEnumerable<T> Find<T>(Expression<Func<T, bool>> predicate) where T : class
    {
        return ???.Where(predicate).ToArray();
    }

    public T GetOne<T>(Expression<Func<T, bool>> predicate) where T : class
    {
        return ???.Where(predicate).FirstOrDefault();
    }

    public void Dispose()
    {
        throw new NotImplementedException();
    }
}

What I am struggling with is where i put the "???" that should be my IdbSet.

How could I Implement my concrete repository?Any suggestions or noddy test sample will do.

many thanks

user9969
  • 14,468
  • 37
  • 101
  • 168

1 Answers1

1

First, you better change the GetAll() and Find() methods to return IQueryable<T> instead of IEnumerable<T>, so that further querying on the dataset would be implemented using Linq-to-Entities.

As of the EF implementation, try something like this:

public class EFRepository : DbContext, IRepository
{
    // ctor:
    // pass a full connecting-string, or "name=someName" from configuration
    public EFRepository(string connectionStringOrName) : base(connectionStringOrName)
    {
          // init sets
          this.Entities1 = this.Set<EntityOfSomeType>();
          this.Entities2 = this.Set<EntityOfOtherType>();
    }

    public IEnumerable<T> GetAll<T>() where T : class
    {
        return this.Set<T>().ToArray();
    }

    public IEnumerable<T> Find<T>(Expression<Func<T, bool>> predicate) where T : class
    {
        return this.Set<T>().Where(predicate).ToArray();
    }

    public T GetOne<T>(Expression<Func<T, bool>> predicate) where T : class
    {
        return this.Set<T>.FirstOrDefault(predicate);
    }

    public void Dispose()
    {
        base.Dispose();
    }

    // Your DbSets...
    public IDbSet<EntityOfSomeType> Entities1 { get; set; }
    public IDbSet<EntityOfAnotherType> Entities2 { get; set; }
}

(I used DbContext with the assumption that you're going code-first)

haim770
  • 45,540
  • 6
  • 91
  • 121
  • @haim770.Thanks for your reply.Yes I am using codefirst. I am new to EF and I am having trouble to get data instantiate a dbset .Is DBContext the lightest EF object?Can it be used in multithreaded enviroments? Any suggestions – user9969 Dec 08 '13 at 08:56
  • `DbContext` is not 'lightest' or 'heaviest', just one of the approaches EF offers to access/model data. see http://stackoverflow.com/questions/5446316/code-first-vs-model-database-first – haim770 Dec 08 '13 at 09:13
  • Thanks.I thought about Iqueryable and I know that there are 2 school of thoughts but I think we should not return Iqueryable outside repository.TOO dangerous.see this as well http://codetunnel.com/blog/post/should-you-return-iqueryablet-from-your-repositories – user9969 Dec 08 '13 at 09:54
  • @haim770.Can I ask you why you instantiate the entities in the constructor?Would you use it like this using (var ctx = new EFRepository(connectionstring)) { var customers = ctx.GetAll().ToList(); } – user9969 Dec 08 '13 at 09:58
  • Yes, you can use it this way. – haim770 Dec 08 '13 at 10:31