1,nhibernate升级到3.2版本后使用odt获取oracle数据时传入的参数需要是skip的参数加上pagesize才行,而在3.1里没有这个问题
2,linq2nhibernate暂时不支持子查询中有group的语句,方式是将子查询返回list再使用contains
3,Query specified join fetching, but the owner of the fetched association was not present in the select list,在query后使用Fetch获取关联对象时如果提示以上错误请将hbm中的文件修改中的fetech修改为select,修改后调用count时也会保存,请再调用fetch调用count方法
4,关于nhibernate对象中lazyload的属性无法进行json转换的问题,参考这个链接实现对延迟加载对象的剔除,但是如果要json化的对象是另一个对象的属性(例如post对象的readers属性),在序列化的时候由于readers属性是延迟加载的实际的类是prxoy类还需要进行转换成实际的类,请使用下面的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Metadata;
using NHibernate.Proxy;
namespace APSP.Common
{
public static class NHibernateProxyUtils
{
/// <summary>
/// Force initialization of a proxy or persistent collection.
/// </summary>
/// <param name="persistentObject">a persistable object, proxy, persistent collection or null</param>
/// <exception cref="HibernateException">if we can't initialize the proxy at this time, eg. the Session was closed</exception>
public static T Unproxy<T>(this T persistentObject)
{
var proxy = persistentObject as INHibernateProxy;
if (proxy != null)
return (T)proxy.HibernateLazyInitializer.GetImplementation();
return persistentObject;
}
/// <summary>
/// Gets the underlying class type of a persistent object that may be proxied
/// </summary>
public static Type GetUnproxiedType<T>(this T persistentObject)
{
var proxy = persistentObject as INHibernateProxy;
if (proxy != null)
return proxy.HibernateLazyInitializer.PersistentClass;
return persistentObject.GetType();
}
/// <summary>
/// Force initialzation of a possibly proxied object tree up to the maxDepth.
/// Once the maxDepth is reached, entity properties will be replaced with
/// placeholder objects having only the identifier property populated.
/// </summary>
public static T UnproxyObjectTree<T>(this T persistentObject, ISessionFactory sessionFactory, int maxDepth)
{
// Determine persistent type of the object
var persistentType = persistentObject.GetUnproxiedType();
var classMetadata = sessionFactory.GetClassMetadata(persistentType);
// If we've already reached the max depth, we will return a placeholder object
if (maxDepth < 0)
return CreatePlaceholder(persistentObject, persistentType, classMetadata);
// Now lets go ahead and make sure everything is unproxied
var unproxiedObject = persistentObject.Unproxy();
// Iterate through each property and unproxy entity types
for (int i = 0; i < classMetadata.PropertyTypes.Length; i++)
{
var nhType = classMetadata.PropertyTypes[i];
var propertyName = classMetadata.PropertyNames[i];
var propertyInfo = persistentType.GetProperty(propertyName);
// Unproxy of collections is not currently supported. We set the collection property to null.
if (nhType.IsCollectionType)
{
propertyInfo.SetValue(unproxiedObject, null, null);
continue;
}
if (nhType.IsEntityType)
{
var propertyValue = propertyInfo.GetValue(unproxiedObject, null);
if (propertyValue == null)
continue;
propertyInfo.SetValue(
unproxiedObject,
propertyValue.UnproxyObjectTree(sessionFactory, maxDepth - 1),
null
);
}
}
return unproxiedObject;
}
/// <summary>
/// Return an empty placeholder object with the Identifier set. We can safely access the identifier
/// property without the object being initialized.
/// </summary>
private static T CreatePlaceholder<T>(T persistentObject, Type persistentType, IClassMetadata classMetadata)
{
var placeholderObject = (T)Activator.CreateInstance(persistentType);
if (classMetadata.HasIdentifierProperty)
{
var identifier = classMetadata.GetIdentifier(persistentObject, EntityMode.Poco);
classMetadata.SetIdentifier(placeholderObject, identifier, EntityMode.Poco);
}
return placeholderObject;
}
}
}