0

我有一个 ObjectDataSource 的选择方法:

    public static IEnumerable<Model.Domain.Theme> Select()
    {
        var cycleRepo = new RbaCycleRepository(Global.sessionFactory.GetCurrentSession());
        RbaCycle lacOpenCycle = cycleRepo.FindLacOpenCycle();
        if (lacOpenCycle != null)
        {
            var themeRepo = new ThemeRepository(Global.sessionFactory.GetCurrentSession());
            var result = themeRepo.FindAll(new ThemesForCycle(lacOpenCycle).GetQuery());
            return result;
        }
        return Enumerable.Empty<Model.Domain.Theme>();
    }

这是场景:

  • 我单击按钮,执行了一些操作,结果我在一级缓存中得到了一些代理主题对象——这很好。
  • 调用Select()方法并返回结果。结果只能包含Theme对象或ThemeNHibernate Castle Proxy的混合(例如)。这是来自监视窗口的跟踪:

{Castle.Proxies.ThemeProxy} Model.Domain.Theme {Castle.Proxies.ThemeProxy} {Model.Domain.Theme} Model.Domain.Theme

  • 如果结果集合中的第一个对象是实际的Theme对象,则整个集合的绑定成功。但是如果集合中的第一个元素是 Proxy object,那么我最终会遇到异常:

未处理的异常:System.Web.HttpUnhandledException:引发了“System.Web.HttpUnhandledException”类型的异常。---> System.Reflection.TargetInvocationException:对象“CIPNet.Model.Domain.Theme”上的属性访问器“Title”引发以下异常:“对象与目标类型不匹配。” ---> System.Reflection.TargetException:对象与目标类型不匹配。

编辑:这是 FindAll 实现:

    public IList<T> FindAll(QueryOver<T, T> query)
    {
        return query.GetExecutableQueryOver(session).List();
    }
4

2 回答 2

0

看起来ObjectDataSource是使用集合的第一个元素来找出数据源的列。由于它使用反射,NHibernate / Castle DynamicProxy 没有机会取消代理对象。您可能需要手动执行此操作。

识别 NHibernate 代理类
NHibernate:获取引用抽象实体的具体类型

此外,如果您的FindAll方法返回IQueriableor IEnumerable,请尝试在结果上调用.ToList()or.ToArray()以强制执行查询。您可能不需要手动取消代理:

var result = 
    themeRepo.FindAll(new ThemesForCycle(lacOpenCycle).GetQuery()).ToList();
于 2012-07-05T09:31:20.443 回答
0

这是我想出的临时解决方案。它有效,我只是确保绑定到控件的列表具有第一个不是代理的对象:

    public static IList<T> ToProxySafeList<T>(this IList<T> list)
        where T: class
    {
        if (list.Count == 0) return list;

        var proxy = list[0] as INHibernateProxy;
        if (proxy != null)
        {
            list[0] = proxy.HibernateLazyInitializer.GetImplementation() as T;
        }
        return list;
    }

有什么建议么?

于 2012-07-05T10:47:48.193 回答