Samples using EntityFramework?

Interface

public interface IDinnerRepository 
{
    IQueryable<Dinner> FindAllDinners();
    IQueryable<Dinner> FindDinnersByText(string q);

    Dinner GetDinner(int id);

    void Add(Dinner dinner);
    void Delete(Dinner dinner);

    void Save();
}

      

Class inherited from the interface above

public class DinnerRepository : NerdDinner.Models.IDinnerRepository
{
    NerdDinnerEntities db = new NerdDinnerEntities();

    Public IQueryable<Dinner> FindDinnersByText(string q)
    {
         return db.Dinners.Where(d => d.Title.Contains(q)
             || d.Description.Contains(q)
             || d.HostedBy.Contains(q));
    }

    public IQueryable<Dinner> FindAllDinners()
    {
         return db.Dinners;
    }

    public Dinner GetDinner(int id)
    {
        return db.Dinners.SingleOrDefault(d => d.DinnerID == id);
    }

    public void Add(Dinner dinner)
    {
        db.Dinners.AddObject(dinner);
    }

    public void Delete(Dinner dinner)
    {
        foreach (RSVP rsvp in dinner.RSVPs.ToList())
            db.RSVPs.DeleteObject(rsvp);

        db.Dinners.DeleteObject(dinner);
   }

   public void Save()
   {
        db.SaveChanges();
   }
}

      

Use in the program

public class DinnerOperation
{
    DinnerRepository dr = new DinnerRepository();

    // insert
    public void InsertDinner()
    {
        Dinner dinner = dr.GetDinner(5);
        dr.Dinner.Add(dinner);
        dr.Save();
    }

    // delete
    public void DeleteDinner()
    {
        Dinner dinner = dr.GetDinner(5);
        dr.Dinner.Delete(dinner);
        dr.Save();
    }
}

      

And without using the repository design pattern ...

public class DinnerOperation
{
    DinnerEntities entity = new DinnerEntities();

    // insert
    public void InsertDinner()
    {
        Dinner dinner = entity.Dinners.Find(5);
        entity.Dinner.Add(dinner);
        entity.SaveChanges();
    }

    // delete
    public void DeleteDinner()
    {
        Dinner dinner = entity.Dinners.Find(5);
        entity.Dinner.Remove(dinner);
        entity.SaveChanges();
    }
}

      

Question

I can't figure out, here, why did we use the design pattern? So when using the repository pattern with Entity Framework, it doesn't mean anything.

How can I use a design pattern with the enitiy framework? When does it make sense to use an entity wireframe design pattern?

+3


source to share


3 answers


You almost got it. First, refactor your working class to implement the repository implementation.

public class DinnerOperation
{
  private IDinnerRepository dr;
  public DinnerOperation( IDinnerRespository repository ) {
     this.dr = repository;
  }

  // insert
  public void InsertDinner()
  {
      Dinner dinner = dr.GetDinner(5);
      dr.Dinner.Add(dinner);
      dr.Save();
  }

  // delete
  public void DeleteDinner()
  {
      Dinner dinner = dr.GetDinner(5);
      dr.Dinner.Delete(dinner);
      dr.Save();
  }
}

      

Then we implement different repositories:

public class EntityFrameworkDinnerRepository : IDinnerRepository
public class NHibernateDinnerRepository : IDinnerRepository
public class Linq2SqlDinnerRepository : IDinnerRepository
public class MockDinnerRepository : IDinnerRepository
....

      

and then use whatever repository you want:

var repository = new ....Repository();
var operation = new DinnerOperation( repository );

operation.GetDinner(5);

      



Repositories are used to abstract your specific data providers and thus make your architecture more free-flowing.

Want to switch to nHibernate?

Soreness if you have EntityFramework everywhere. It's easy if you are using repositories, you just inject another repository and your business logic should not change.

Want to unit test your business logic?

Soreness if you stick to a specific data provider. It's easy if you have repositories you just inject inmemory a repository that doesn't even use the database.

Has he received it now?

+6


source


I refuse to use the repository pattern when I use the ORM. I think it is of very little use in this case. (Yes, I expect about 2,000 voted out of hunger.)

With EF I am creating an interface for my context

public interface IDinnerContext : IDisposable
{
    IDbSet<Dinner> Dinners;

    int SaveChanges();
}

      



Then I stick with this interface in my EF DatabaseContext and viola implementations! I can use EF everywhere, unit test my db access with MOCK implementations, use injection if I want, not end up with 6 million GetByXXX methods. IQeryable handles this and I get execution delay. I don't need the Insert / Delete methods because IDBSet is already adding / removing. My code is cleaner / easier to read with less abstraction.

If I have a case where the same query is used in many different places and I really want it to be generic, then I can add some mechanism to support that. However, 95% of the time, requests are specific to the component responsible for business logic X (anything outside of simple GetBy statements). Therefore, I do not see this as a problem.

Don't get me wrong, I used the storage pattern religiously until the ORMs got pretty decent. Once the ORMs reached a certain level of sophistication, I felt that the repository pattern was no longer required and started doing projects without it .... and NEVER looked back. I think everyone else will eventually follow in that direction or something very similar, but old habits will take a while. (I know some developers who still insist on using locking (this) because they are still in some MS samples).

+5


source


This is a repository pattern , which on its own would be weird with the Entity Framework because it DbContext

serves as both a repository and a unit of work at the same time, but it's not mocked - it's not there IDbContext

. This way you push DbContext

into a thin package of the repository so that you can test components easily afterwards.

I think it is worth mentioning that I have never used the repository pattern with NHibernate, because the session and the factory session are interfaces - ISession

and ISessionFactory

accordingly.

If you are using a repository on an interface somewhere ( IRepository

) and injecting it, mocking / stubbing testing will be much easier:

public class DinnerOperation
{
    private readonly IDinnerRepository repository;

    public DinnerOperation(IDinnerRepository dinnerRepository)
    {
        repository = dinnerRepository;
    }
}

      

Of course, you will need to use an IoC container to select the correct instance for you ( DinnerRepository

in this case) or DI 'manually'.

This way you can test the class DinnerOperation

against a mock or dived repository. When you instantiate DbContext

, you cannot.

+2


source







All Articles