Quantcast
Channel: Entity Framework
Viewing all articles
Browse latest Browse all 10318

Created Issue: UpForGrabs: Polymorphic removal of objects added to an ObjectSet will NOT raise the IBindingList.ListChanged event on the IBindingList returned by the ObjectSet.IListSource.GetList() method. [620]

$
0
0
Deleting objects of derived entity types added to an ObjectSet will NOT raise the ListChanged event on the internal IBindingList of the the ObjectSet as a IListSource. Note: ObjectSet extends ObjectQuery which implements IListSource. Removal of instances whose runtime type match TEntity are notified on the ListChanged event. At all times, objects are effectively removed from the underlying collections, it's just that these don't get notified when the objects removed derive from the entity type passed as generic type parameter. Reseach: Through reflector found that the actual IBindingList returned is of type ObjectView, and this type delegates removal operations to an internal IObjectViewData. The implementation found for that interface is ObjectViewQueryResultData which defines: public ListChangedEventArgs OnCollectionChanged(object sender, CollectionChangeEventArgs e, ObjectViewListener listener) { ListChangedEventArgs changeArgs = null; if (e.Element.GetType().IsAssignableFrom(typeof(TElement)) && _bindingList.Contains((TElement) (e.Element))) { ... changeArgs = new ListChangedEventArgs(ListChangedType.ItemDeleted, ...); ... } return changeArgs; }
Fri, 6/15/2012 1:43 PM (show all changes)



Repro Steps:

------- Model -------

This is the entity hierarchy (pseudo-UML):

FiascoEntityContext : ObjectContext
+ Foos : ObjectSet<Foo>

Foo : EntityObject
+ Id: Int32
+ Name: String

SpecialFoo : Foo
+ SpecialProperty: String

------- Setup -------

1. Table per Type Strategy
2. Entity model mapped and validated against gemerated SQL database on Server 2012 Express.

------- Issue -------

Code that isolates the problem:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Data.Objects;

namespace FiascoEF {
class Program {
static void Main(string[] args) {
using (FiascoEntityContext context = new FiascoEntityContext()) {
//
// add some foos
//
context.Foos.AddObject(new Foo { Name = "Foo1" });
context.Foos.AddObject(new BetterFoo { Name = "BetterFoo1", SpecialProperty = "Something Special" });
context.SaveChanges();
//
// show the contents
//
Console.WriteLine("Listing all foos:");
foreach (var foo in context.Foos) {
Console.WriteLine(" Got {0}: Id={1} Name={2} (State={3})", foo, foo.Id, foo.Name, foo.EntityState);
}
//
// attach handler for the ListChanged event of the IBindingList returned by context.Foos as IListSource
// NOTE: have to do this here bacause SaveChanges() above will reset the internal IBindingList
//
var bindingList = (context.Foos as IListSource).GetList() as IBindingList;
bindingList.ListChanged += new ListChangedEventHandler(bindingList_ListChanged);
//
// delete all foos and show state. expect the event handler above to be invoked.
//
Console.WriteLine("Deleting all foos:");
foreach (var foo in context.Foos) {
context.Foos.DeleteObject(foo);
Console.WriteLine(" Deleted {0}: Id={1} Name={2} (State={3})", foo, foo.Id, foo.Name, foo.EntityState);
}
context.SaveChanges();
}
}

static void bindingList_ListChanged(object sender, ListChangedEventArgs e) {
Console.WriteLine(" Event on {0}: {1}", sender, e.ListChangedType);
}
}
}

Actual Results:
Listing all foos:
Got FiascoEF.Foo: Id=257 Name=Foo1 (State=Unchanged)
Got FiascoEF.BetterFoo: Id=258 Name=BetterFoo1 (State=Unchanged)
Deleting all foos:
Event on System.Data.Objects.ObjectView`1[FiascoEF.Foo]: ItemDeleted
Deleted FiascoEF.Foo: Id=257 Name=Foo1 (State=Deleted)
Deleted FiascoEF.BetterFoo: Id=258 Name=BetterFoo1 (State=Deleted)

Expected Results:
Listing all foos:
Got FiascoEF.Foo: Id=257 Name=Foo1 (State=Unchanged)
Got FiascoEF.BetterFoo: Id=258 Name=BetterFoo1 (State=Unchanged)
Deleting all foos:
Event on System.Data.Objects.ObjectView`1[FiascoEF.Foo]: ItemDeleted
Deleted FiascoEF.Foo: Id=257 Name=Foo1 (State=Deleted)
Event on System.Data.Objects.ObjectView`1[FiascoEF.Foo]: ItemDeleted
Deleted FiascoEF.BetterFoo: Id=258 Name=BetterFoo1 (State=Deleted)

Viewing all articles
Browse latest Browse all 10318

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>