Search code examples
c#databaseentity-frameworkdata-access-layer

Change EF entity with descendant proxy class


I have .Net 4.0 application which use EntityFramework 5.0 to access data from MS SQL database.

I use database first approach. All tableas are mapped to POCO entities, which has additional properties which contains entities which is recieved from web service.

Database:

WH_Product (Id, NomenklatureId, SeriesId, Quantity)

Service have such data:

Nomenklature (Id, Name, Producer...)
Series (Id, Number, Date...)

POCO entity:

Product (Id, NomenklatureId, Nomenklature, SeriesId, Series, Quantity)

I have a problem with Repository realisation. I need to implement lazy loading for Nomenklature and Series properties.

I make ProductProxy class which implements such loading like this:

public class ProductProxy:Product
{

   private Nomenklature _nomenklature;
   public override Nomenklature Nomenklature
   {
      get
      {
         if (_nomenklature==null)
         {
            _nomenklature = <code for load Nomenklature from webService by base.NomenklatureId>
         }
         return _nomenklature;
      }
   }

   private Series _series;
   public override Series Series
   {
      get
      {
         if (_series==null)
         {
            _series = <code for load Series from webService by base.NomenklatureId>
         }
         return _series;
      }
   }
}

Then change Person class to PersonProxy class in DbContext.

public class ProductContext:DbContext
{
   ...
   public DbSet<PersonProxy> Person {get; set;}
   ...
}

The load method:

public List<Person> GetPersons()
{
    using (var ctx = new ProductContext())
    {
        var persons = ctx.Person.AsEnumerable().Cast<Person>().ToList();
        return persons;
    }
}

Question: Is this a better way to realize GetPersons method without AsEnumerable().Cast()? Is this another way of changing the entity type with the descendant proxy type?


Solution

  • The Proxy pattern is taking advantage of Polymorphism (one of 'The 3 Pillars of OOP'), the consumer of the object think it deals with a Person while in-fact he's dealing with a PersonProxy. that is possible because PersonProxy is a Person because it derives from it.

    That's why you can write:

    Person person = new PersonProxy();
    

    Then in your case, your GetPersons() method could simply return IEnumerable<Person>, as follows:

    public IEnumerable<Person> GetPersons()
    {
        using (var ctx = new ProductContext())
        {
            return ctx.Person;
        }
    }