【问题标题】:NHibernate proxy causing problems with databindingNHibernate 代理导致数据绑定问题
【发布时间】:2009-05-28 10:43:45
【问题描述】:
我有一个绑定到 nhibernate 查询结果的 gridview。如果编辑列表中的第一项,则会引发以下异常:
System.Reflection.TargetException: Object does not match target type
问题似乎是由于数据绑定无法处理列表中的第一项是列表中其他项的子类型。
解决这个问题的好方法/正确方法是什么?目前我不得不关闭 nhibernates 代理。
编辑:我还有另外几个解决方案:
但是这些都不对...
【问题讨论】:
标签:
c#
asp.net
nhibernate
proxy
data-binding
【解决方案2】:
根本原因是由于列表中的代理对象(来自延迟加载)还是因为列表不是同质的(即使它们属于同一个类层次结构也包含多个类型)?非同质数据集的问题是一个已知的限制。请参阅this 和this。
我认为除了不使用数据绑定来填充网格之外没有其他解决方案。如果它是只读的,那就很容易了。
【解决方案3】:
我不直接在视图中使用我的域对象。相反,我使用 MVVM 模式并创建合适的视图模型来保存非代理对象。
【解决方案4】:
如果你知道你将要对它进行数据绑定,另一个解决方案是加入获取关系。例如。添加.SetFetchMode(“人”,FetchMode.Join)。 NHibernate 应该只返回域对象,因为它们都不应该被延迟加载。
【解决方案5】:
很晚,但应该可以帮助其他有同样问题的人。
我使用的解决方案是在 getter 中的字段周围包装一个自定义列表(在本例中为 NotificationList)。
private IList<IParameter> _parameters = new List<IParameter>();
get
{
return new NotificationList<IParameter>(_parameters);
}
此列表是列表的包装器,因此数据绑定将被转发到原始列表。
public class NotificationList<T> : IList, IList<T>
{
IList<T> myList;
public NotificationList(IList<T> list)
{
myList = list;
}
int IList.Add(object item)
{
myList.Add ((T) item);
}
// implement both IList<T> and IList
// ...
}
对我来说,这解决了数据绑定的问题,但产生了一个副作用,即每次刷新会话时,集合中的所有项目都会在数据库中更新,无论它们是否更改。为了解决这个问题,我更改了映射以直接访问该字段。请参阅 Hibernate 上的 this,它也适用于 NHibernate。
这是新的 (Fluent) 映射:
HasMany(x => x.Parameters)
.Cascade.All()
.Access.CamelCaseField(Prefix.Underscore);