3

Is there any way to determine when actual items are added to an ICollection<> virtual member when it is being loaded from a query?

Hopefully the code below will be able to demonstrate my point!!

public class DbAppointment
{
    public DbAppointment()
    {
    }

    public virtual int AppointmentId { get; set; }
    public virtual string Subject { get; set; }
    public virtual string Body { get; set; }
    public virtual DateTime Start { get; set; }
    public virtual DateTime End { get; set; }

   private ICollection<DbExceptionOcurrence> exceptionOcurrences;
   public virtual ICollection<DbExceptionOcurrence> ExceptionOcurrences
   {
        get { return exceptionOcurrences; }
        set
        {
            exceptionOcurrences = value;
        }
    }
}

and

public class DbExceptionOcurrence
{
    public DbExceptionOcurrence()
    {
    }

    public virtual int ExceptionId { get; set; }
    public virtual int AppointmentId { get; set; }
    public virtual DateTime ExceptionDate { get; set; }
    public virtual DbAppointment DbAppointment { get; set; }
}

The code for loading these is

        Database.SetInitializer(new ContextInitializer());
        var db = new Context("EFCodeFirst");

        // when this query executes the DbAppointment ExceptionOcurrenes (ICollection) is set
        // but for some reason I only see this as an empty collection in the virtual setter DbAppointment
        // once the query has completed I can see the ExceptionOcurrences
        var result = db.Appointments.Include(a => a.ExceptionOcurrences).ToList();

In the DbAppointment ICollection ExceptionOcurrences setter for each item I need to perform some addtional logic. The problem I am having is that I only seem to have this information once the DbAppointment objects have already been created.

Is there any way to determine when the items have been added so I can perform my logic.

Cheers Abs

user1460473
  • 115
  • 9

1 Answers1

2

Apparently the behaviour you are seeing means that Entity Framework creates and fills the collection similar to this:

// setter called with empty collection
dbAppointment.ExceptionOcurrences = new HashSet<DbExceptionOcurrence>();

// only getter gets called now
dbAppointment.ExceptionOcurrences.Add(dbExceptionOcurrence1);
dbAppointment.ExceptionOcurrences.Add(dbExceptionOcurrence2);
dbAppointment.ExceptionOcurrences.Add(dbExceptionOcurrence3);
//...

I had hoped that you can use the ObjectMaterialized Event (can be registered with DbContext like in this example: https://stackoverflow.com/a/4765989/270591, the EventArgs contain the materialized entity) but unfortunately the documentation says:

This event is raised after all scalar, complex, and reference properties have been set on an object, but before collections are loaded.

It looks that you have to run through the result collection after it has been loaded completely and call some method on each result item which performs your custom logic on the navigation collection.

Maybe another option is create a custom collection type that implements ICollection<T> with an event handler for the Add method and allows you to hook in some logic everytime a new item is added. Your navigation collection in the model class would have to be of that type. Maybe even ObservableCollection<T> is fine for this purpose.

Community
  • 1
  • 1
Slauma
  • 175,098
  • 59
  • 401
  • 420
  • 1
    The last paragraph should lead toward a solution. Just use either ObservableCollection or custom collection with custom Add method and some OnAdd event. You can use OnMaterialized event to initialize the collection and register event handler. Than your event will be fired every time EF will add entity to the collection. – Ladislav Mrnka Jun 16 '12 at 14:45
  • I was hoping for the same too!! But when I created a custom collection that inherits from Collection and overrides InsertItem. This still failed to capture the new item :( – user1460473 Jun 16 '12 at 18:51
  • @user1460473: Perhaps create a new question where you describe the steps you have done in detail and what exactly fails... – Slauma Jun 16 '12 at 23:53
  • @Slauma: Thanks for suggesting this. I am new to this and wouldn't have thought of that. Anyway here is the link to my related question http://stackoverflow.com/questions/11071942/ef-4-3-code-first-custom-icollection-fails-to-catch-new-items – user1460473 Jun 17 '12 at 14:16
  • @Slauma: Thanks... your suggestion worked (see related post http://stackoverflow.com/questions/11071942/ef-4-3-code-first-custom-icollection-fails-to-catch-new-items) – user1460473 Jun 17 '12 at 17:00