它看起來每個I查詢一些與LINQ NHibernate的時間一樣從頭開始構建該查詢:如何緩存編譯的LINQ查詢(不是結果)?
代碼看起來像
session.Query<User>().Where(x => ids.Contains(x.Id)).ToFuture();
是否有可能避免重新編譯呢?
關於緩存QueryOver/Criteria查詢的相同問題(不是很重要,但它可能仍然適合範圍)。
它看起來每個I查詢一些與LINQ NHibernate的時間一樣從頭開始構建該查詢:如何緩存編譯的LINQ查詢(不是結果)?
代碼看起來像
session.Query<User>().Where(x => ids.Contains(x.Id)).ToFuture();
是否有可能避免重新編譯呢?
關於緩存QueryOver/Criteria查詢的相同問題(不是很重要,但它可能仍然適合範圍)。
特別是這種情況下被接入到IDS(int[]
)造成這裏
session.Query<User>().Where(x => ids.Contains(x.Id)).ToFuture();
轉化MemberAccessExpression
(不ConstantExpression
)和NHibernate不得不對其進行評估。儘管ids
從未被更改過,但它仍被捕獲到一個關閉生成的類中(如DisplayClass<>.ids
)。
我通過製作PartialEvaluatingExpressionTreeVisitor
我自己的版本優化,這種情況下:
protected Expression EvaluateSubtree(Expression subtree)
{
ArgumentUtility.CheckNotNull(nameof(subtree), subtree);
var memberExpression = subtree as MemberExpression;
if (memberExpression != null)
{
Expression constant;
if (TryEvaluateMember(memberExpression, out constant)) return constant;
}
if (subtree.NodeType != ExpressionType.Constant)
throw new NHibernateExpressionOptimizerException(subtree);
ConstantExpression constantExpression = (ConstantExpression)subtree;
IQueryable queryable = constantExpression.Value as IQueryable;
if (queryable != null && queryable.Expression != constantExpression)
return queryable.Expression;
return constantExpression;
}
bool TryEvaluateMember(MemberExpression memberExpression, out Expression constant)
{
constant = null;
ConstantExpression c = memberExpression.Expression == null ? Expression.Constant(null) : EvaluateSubtree(memberExpression.Expression) as ConstantExpression;
if (c == null) return false;
var fieldInfo = memberExpression.Member as FieldInfo;
if (fieldInfo != null)
{
constant = Expression.Constant(ReflectorReadFieldDelegate(fieldInfo, c.Value));
return true;
}
var propertyInfo = memberExpression.Member as PropertyInfo;
if (propertyInfo != null)
{
constant = Expression.Constant(ReflectorReadPropertyDelegate(propertyInfo, c.Value));
return true;
}
return false;
}
反射器代表使用一種緩存Reflection.Emit的魔力。
這聽起來像改變了我一般不喜歡的默認行爲。爲什麼不把它包裝在一個方法調用中,如公共靜態T ToConst
@stybl「重用LINQ查詢」和「重用LINQ到數據庫NH查詢」是不一樣的東西 – Vlad
我知道,這就是爲什麼我撤回了近距離投票。雖然忘記了評論。 – stybl
https://stackoverflow.com/a/4817010/1162077 –