0

ObjectDataSourceのselectメソッドがあります。

    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>();
    }

そして、ここにシナリオがあります:

  • ボタンをクリックすると、いくつかのアクションが実行され、その結果、第1レベルのキャッシュにいくつかのプロキシテーマオブジェクトが作成されます。これは問題ありません。
  • Select()メソッドが呼び出され、結果が返されます。結果には、テーマオブジェクトのみ、またはテーマNHibernate Castleプロキシの組み合わせ(たとえば)を含めることができます。これはウォッチウィンドウからのトレースです。

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

  • 結果コレクションの最初のオブジェクトが実際のテーマオブジェクトである場合、コレクション全体のバインドは成功します。しかし、コレクションの最初の要素がProxyオブジェクトである場合、例外が発生します。

未処理の例外: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 /CastleDynamicProxyはオブジェクトのプロキシを解除する機会がありません。おそらく手動で行う必要があります。

NHibernateプロキシクラスの識別NHibernate
:参照される抽象エンティティの具体的なタイプを取得します

また、FindAllメソッドがIQueriableまたはを返す場合は、または結果IEnumerableを呼び出して、クエリを強制的に実行してみてください。手動でプロキシを解除する必要がない場合があります。.ToList().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 に答える