Question

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?

Was it helpful?

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;
    }
}

OTHER TIPS

If you value your entity classes being light, you could approach this differently, without putting loading logic in descendant proxies.

Instead, keep you entity classes simple and have them loaded externally after they're created (materialized).

Ladislav's answer shows how to get to the event that fires after every entity object is created. If you use this approach, subscribe to it with a handler, that distinguishes different entity classes and loads them appropriately - there's a lot of clean ways to do this.

Do note that if lazy loading of these properties is beneficial to you, this approach will probably not be useful.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top