ISession.Load(id)“创建代理实例失败”“序列包含多个匹配元素”

问题描述 投票:0回答:1

我正在从非常旧的 NHibernate 版本(2.1 到 5.5)升级应用程序。应用程序构建并运行,并且它正在从数据库读取实体/向数据库写入实体。

但是,当调用 ISession.Load 时,出现以下异常:

Creating a proxy instance failed
at NHibernate.Proxy.StaticProxyFactory.GetProxy(Object id, ISessionImplementor session)
at NHibernate.Event.Default.DefaultLoadEventListener.CreateProxyIfNecessary(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options, IPersistenceContext persistenceContext)
at NHibernate.Event.Default.DefaultLoadEventListener.ProxyOrLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType)
at NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType)
at NHibernate.Impl.SessionImpl.Load(String entityName, Object id)
at NHibernate.Impl.SessionImpl.Load[T](Object id)

INNER EXCEPTION:
Sequence contains more than one matching element
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
at NHibernate.Proxy.ProxyBuilderHelper.GenerateMethodSignature(String name, MethodInfo method, TypeBuilder typeBuilder)
at NHibernate.Proxy.NHibernateProxyBuilder.ImplementCallMethodOnImplementation(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField, Type parentType)
at NHibernate.Proxy.NHibernateProxyBuilder.CreateProxiedMethod(TypeBuilder typeBuilder, MethodInfo method, FieldInfo lazyInitializerField, Type parentType)
at NHibernate.Proxy.NHibernateProxyBuilder.CreateProxyType(Type baseType, IReadOnlyCollection`1 baseInterfaces)
at NHibernate.Proxy.StaticProxyFactory.CreateProxyActivator(ProxyCacheEntry pke)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at NHibernate.Proxy.StaticProxyFactory.GetProxy(Object id, ISessionImplementor session)

我查看了NHibernate的ProxyBuilderHelper的源代码,看看GenerateMethodSignature中哪里调用了SingleOrDefault,就在这里:

var typeArgs = method.GetGenericArguments();
if (typeArgs.Length > 0)
{
    var typeNames = GenerateTypeNames(typeArgs.Length);
    var typeArgBuilders = methodBuilder.DefineGenericParameters(typeNames);

    for (var index = 0; index < typeArgs.Length; index++)
    {
        // Copy generic parameter attributes (Covariant, Contravariant, ReferenceTypeConstraint,
        // NotNullableValueTypeConstraint, DefaultConstructorConstraint).
        var typeArgBuilder = typeArgBuilders[index];
        var typeArg = typeArgs[index];

        typeArgBuilder.SetGenericParameterAttributes(typeArg.GenericParameterAttributes);

        // Copy generic parameter constraints (class and interfaces).
        var typeConstraints = typeArg.GetGenericParameterConstraints()
            .ToArray(x => ResolveTypeConstraint(method, x));

        var baseTypeConstraint = typeConstraints.SingleOrDefault(x => x.IsClass);
        typeArgBuilder.SetBaseTypeConstraint(baseTypeConstraint);

        var interfaceTypeConstraints = typeConstraints.Where(x => !x.IsClass).ToArray();
        typeArgBuilder.SetInterfaceConstraints(interfaceTypeConstraints);
    }
}

它获取泛型类型参数的一组约束,然后尝试找到“IsClass == true”的约束,显然有多个约束。我不知道这意味着什么或如何解决它。

这是调用方法。类型约束是针对类的:

public TEntity GetProxy<TEntity>(Guid id) where TEntity : Entity
{
    ...
    return Session.Load<TEntity>(id);
}
c# nhibernate
1个回答
0
投票

我的实体类的方法之一具有具有多个目标类的子类类型约束,例如

protected virtual SomeMethod<T>(T arg): where T: Foo, Bar

不是

:
之后的逗号分隔列表。 NHibernate 对此感到窒息,因为代理生成代码中的这段代码(ProxyBuilderHelper.cs 中的 GenerateMethodSignature()):

var typeConstraints = typeArg.GetGenericParameterConstraints()
      Select(x => ResolveTypeConstraint(method, x));

var baseTypeConstraint = typeConstraints.SingleOrDefault(x => x.IsClass);

IsClass == true 存在多个类型约束,因此 SingleOrDefault 会抛出异常。

在这种情况下,我能够删除第二种类型的约束,并且问题得到解决。

© www.soinside.com 2019 - 2024. All rights reserved.