我正在使用NHibernate版本3.4.0.400我尝试使用二级缓存以下列方式查询嵌套集合:
_session
.QueryOver()
.Left.JoinAlias(x => x.Parent,() => parent)
.Left.JoinAlias(x => x.Children, () => children)
.TransformUsing(Transformers.DistinctRootEntity)
.Cacheable()
.CacheMode(CacheMode.Normal)
.Future();
但是我收到了一个无效的强制转换异常:
NHibernate.PropertyAccessException was unhandled by user code
Message=Exception occurred getter of Project.Domain.Entities.EntityBase.Id
InnerException: System.Reflection.TargetException
Message=Object does not match target type.
Source=mscorlib
StackTrace:
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at NHibernate.Properties.BasicPropertyAccessor.BasicGetter.Get(Object target)
我在网上搜索过,并且在早期版本中说过bug was fixed already。但它似乎不是。
TransformUsing
语句会导致错误消失。实体:
public class Role : EntityBase
{
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual Role Parent { get; set; }
public virtual IList<Role> Children { get; set; }
}
映射:
public class RoleMap : ClassMap<Role>
{
public RoleMap()
{
Id(x => x.Id);
Map(x => x.Name);
Map(x => x.Description);
References(x => x.Parent, "ParentId").Nullable();
HasMany(x => x.Children).Cascade.SaveUpdate().KeyColumn("ParentId");
Cache.ReadOnly();
}
}
配置:
var cfg = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2012
.ConnectionString(connectionString)
.ShowSql()
.Driver<Sql2008ClientDriver>()
.Provider<DriverConnectionProvider>()
.Dialect<MsSql2008Dialect>())
.Cache(c => c.ProviderClass<SysCacheProvider>().UseQueryCache().UseSecondLevelCache())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<EntityBase>().Conventions.Add(DynamicUpdate.AlwaysTrue()))
.ExposeConfiguration(config =>
{
config.SetInterceptor(new SqlStatementInterceptor());
config.SetProperty(Environment.SqlExceptionConverter, typeof(MsSqlExceptionConverter).AssemblyQualifiedName);
config.Properties[Environment.CurrentSessionContextClass] = "web";
}).BuildConfiguration();
如果有任何线索请分享。谢谢