NHibernate proxy causing problems with databinding

2019-02-25 01:07发布

I have a gridview that is bound to the result from an nhibernate query. If the first item in the list is edited the following exception is thrown:

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

It appears that the problem is caused by the fact that databinding can't deal with the first item in the list being a subtype of the other items in the list.

What is a nice / correct way to solve this problem? Currently I have had to turn off nhibernates proxying.

Edit: I have another couple of solutions:

But none of these feel right though...

5条回答
放我归山
2楼-- · 2019-02-25 01:52

Very late, but should help others with the same problem. The solution I used is to wrap a custom list (in this case a NotificationList) around the field in the getter.

private IList<IParameter> _parameters = new List<IParameter>();  
get  
{  
    return new NotificationList<IParameter>(_parameters);  
}

This list is a wrapper around the list, so that databinding will be forwarded to the original list.

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
    // ...
}

For me this fixed the issue with the databinding, but created a side effect where every time the session was flushed all the items in the collection get updated in the DB, wether they changed or not. To resolve that, I changed the mapping to access the field directly. See this on Hibernate, which applies to NHibernate as well.
This is the new (Fluent) mapping:

HasMany(x => x.Parameters)
       .Cascade.All()
       .Access.CamelCaseField(Prefix.Underscore);
查看更多
兄弟一词,经得起流年.
3楼-- · 2019-02-25 01:59

Is the root cause due to a proxy object in the list (from lazy loading) or because the list isn't homogeneous (contains multiple types even if they belong to the same class hierarchy)? The problem with non-homogeneous data sets is a known limitation. See this and this.

I don't think there's a solution other than to not use databinding to populate the grid. That's easy enough if it's read-only.

查看更多
老娘就宠你
4楼-- · 2019-02-25 02:00

I don't use my domain objects in directly in the views. Instead I use the MVVM pattern and create suitable view models that holds non-proxied objects.

查看更多
闹够了就滚
5楼-- · 2019-02-25 02:04

Another solution is to Join Fetch the relation if you know you are going to be Databinding it. E.g. add .SetFetchMode("People", FetchMode.Join). NHibernate should return only domain objects since none of them should be lazy loaded.

查看更多
看我几分像从前
6楼-- · 2019-02-25 02:05

Maybe too late, but I'd just like to throw this into the ring, here is a solution that I've used for this.

It is also called 'SafeBindingList' like the other suggestion above, but, it does not 'clone' objects to solve the problem. It looks at the objects in the list, then if none proxied, the list is returned unmodified. If one or more objects are proxied, it adds an empty proxy to the non-proxied objects, thus making them all the same type.

So, instead returning a List[T] to bind to, use SafeBindingList[T] to ensure all objects have the same type.

This is updated for the version of Castle used with NH2.0.1: http://code.google.com/p/systembusinessobjects/source/browse/trunk/System.BusinessObjects.Framework/Data/SafeBindingLists.cs

Also, credit goes to the original code and poster: https://forum.hibernate.org/viewtopic.php?t=959464&start=0&postdays=0&postorder=asc&highlight=

查看更多
登录 后发表回答