NHibernate代理导致数据绑定问题

时间:2009-05-28 10:43:46

标签: c# asp.net nhibernate proxy data-binding

我有一个绑定到nhibernate查询结果的gridview。如果编辑列表中的第一项,则抛出以下异常:

System.Reflection.TargetException: Object does not match target type

问题似乎是由于数据绑定无法处理列表中第一项是列表中其他项的子类型这一事实。

解决此问题的好方法是什么?目前我不得不关闭代理人。

编辑:我还有另外几个解决方案:

但这些都不是正确的......

5 个答案:

答案 0 :(得分:3)

也许为时已晚,但我只是想把它扔进戒指,这是我用过的解决方案。

它也像上面的其他建议一样被称为'SafeBindingList',但它不会'克隆'对象来解决问题。它查看列表中的对象,如果没有代理,则返回未修改的列表。如果代理了一个或多个对象,它会向非代理对象添加一个空代理,从而使它们具有相同的类型。

因此,返回一个List [T]来绑定,使用SafeBindingList [T]来确保所有对象具有相同的类型。

这是针对与NH2.0.1一起使用的Castle版本更新的: http://code.google.com/p/systembusinessobjects/source/browse/trunk/System.BusinessObjects.Framework/Data/SafeBindingLists.cs

此外,还可以使用原始代码和海报: https://forum.hibernate.org/viewtopic.php?t=959464&start=0&postdays=0&postorder=asc&highlight=

答案 1 :(得分:2)

根本原因是由于列表中的代理对象(来自延迟加载)还是因为列表不是同类的(即使它们属于同一个类层次结构,也包含多个类型)?非同类数据集的问题是已知的限制。请参阅thisthis

我认为除了不使用数据绑定来填充网格之外,还有其他解决方案。如果它是只读的,这很容易。

答案 2 :(得分:0)

我不直接在视图中使用我的域对象。相反,我使用MVVM模式并创建包含非代理对象的合适视图模型。

答案 3 :(得分:0)

另一种解决方案是,如果您知道要将数据绑定它,请加入获取关系。例如。添加.SetFetchMode(“People”,FetchMode.Join)。 NHibernate应该只返回域对象,因为它们都不应该是延迟加载的。

答案 4 :(得分:0)

很晚,但应该帮助其他人解决同样的问题。 我使用的解决方案是在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 这是新的(流利的)映射:

HasMany(x => x.Parameters)
       .Cascade.All()
       .Access.CamelCaseField(Prefix.Underscore);