0
我想標題說明了我在找什麼。這是我想要實現的一個例子。遍歷/轉換表達樹的好例子
我有實體(其中一些在運行時生成與CodeDom中)
public abstract class Content
{
public virtual Page Parent { get; set; }
public virtual ISet<Property> Properties { get; set; }
// T GetPropertyValue<T>(string)
// SetPropertyValue(string, object)
}
public abstract class Page : Content
{
public virtual string Path { get; set; }
}
// Generated with CodeDom
public class Post : Page
{
public virtual string Text
{
get
{
// get value from Properties
return GetPropertyValue<string>("Text");
}
set
{
// set value to Properties
SetPropertyValue("Text", value);
}
}
}
我使用NHibernate的查詢項目。
問題:我不能在Where子句中使用Post.Text
。
解決方案:創建自己的擴展方法,將lambda表達式轉換爲另一種格式。
E.g查詢
var posts = session.Query<Post>().Filter(p =>
p.Parent.Path.StartsWith("/blogs/programming/") &&
p.Text.Contains("hello"));
有可能轉化到以下任一
public static IQueryable<T> Filter<T>(this IQueryable<T> query, Expression<Func<T, bool>> filterExpr)
{
return query.Where(p =>
p.Parent.Path.StartsWith("/blogs/programming/") &&
p.Properties.OfType<StringProperty>().Any(p2 =>
p2.Name == "Text" &&
p2.StringValue.Contains("hello")));
}
public static IQueryable<T> Filter<T>(this IQueryable<T> query, Expression<Func<T, bool>> filterExpr)
{
var ids1 = session.Query<Content>().Where(p =>
p.Parent.Path.StartsWith("/blogs/programming/"))
.Select(p => p.Id);
var ids2 = session.Query<StringProperty>().Where(p =>
p.Name == "Text" &&
p.StringValue.Contains("hello"))
.Select(p => p.Content.Id);
var ids = ids1.Intersect(ids2);
return query.Where(p => ids.Contains(p.Id));
}
任何好的非簡單的例子或開源項目?