- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
概述/描述
简单:从TEntity
中派生 的运行时类型对象的多态删除添加到 ObjectSet<TEntity>
不会提高 IBindingList.ListChanged
IBindingList
上的事件ObjectSet<TEntity>.IListSource.GetList()
返回的对象方法。
但是,删除运行时类型匹配 的实例 TEntity
在 ListChanged
上得到有效通知事件。
为了澄清,在任何时候,对象都有效地从底层集合或数据 View /存储中删除,但是当这些对象是严格从实际 TEntity
派生的类型的实例时用过,ListChanged
不会引发事件以通知其删除。
对于集合的运行时多态性的适当数据绑定(bind)支持而言,这只是一个现象性的 BUG。
复制
模型设置
这是实体层次结构(伪 UML):
FiascoEntityContext : ObjectContext
+ Foos : ObjectSet<Foo>
Foo : EntityObject
+ Id: Int32
+ Name: String
SpecialFoo : Foo
+ SpecialProperty: String
演示代码
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);
}
}
}
预期结果
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)
实际结果
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)
研究
通过反射器发现实际IBindingList
返回的类型是 ObjectView<TElement>
,并且此类型将删除操作委托(delegate)给内部 IObjectViewData<TElement>
.为该接口(interface)找到的实现是 ObjectViewQueryResultData<TElement>
其中定义:
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;
}
支票:
if (e.Element.GetType().IsAssignableFrom(typeof(TElement)) && ...) { ... }
似乎是假的...可能是以下内容?
if (typeof(TElement).IsAssignableFrom(e.Element.GetType()) && ...) { ... }
最佳答案
很公平,向 Microsoft 报告了错误 — http://connect.microsoft.com/VisualStudio/feedback/details/749368 ...他们似乎已经承认了这个问题,但不清楚他们将做什么。
请记住,我们谈论的是 IBindingList
ObjectSet<T>
检索到的实现当被视为 IListSource
出于数据绑定(bind)的目的,因此预计会触发事件,就像在同类列表的情况下一样。
我通过定义一个继承自 ObservableCollection<T>
的类来摆脱困境并包装 ObjectSet<T>
, 然后执行 IListSource
在 DbExtensions.ToBindingList<T>(this ObservableCollection<T>)
的帮助下扩展方法。
或者,我可以继续并开始使用 DbContext
完全是 API,但定义了我自己的 ObservableCollection<T>
允许我继续使用 ObjectContext
现在,这就是我想要的。
关于c# - 添加到 ObjectSet<TEntity> 的对象的多态移除不会引发 ObjectSet<TEntity>.IListSource.GetList() 上的 IBindingList.ListChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11061548/
我来自 Asp.Net 世界,试图理解 Angular State 的含义。 什么是 Angular 状态?它类似于Asp.Net中的ascx组件吗?是子页面吗?它类似于工作流程状态吗? 我听到很多人
我一直在寻找 3 态拨动开关,但运气不佳。 基本上我需要一个具有以下状态的开关: |开 |不适用 |关 | slider 默认从中间开始,一旦用户向左或向右滑动,就无法回到N/A(未回答)状态。 有人
我是一名优秀的程序员,十分优秀!