遍历/转换表达式树的好例子

时间:2012-05-30 12:07:46

标签: c# linq

我想标题会说明我在寻找什么。这是我想要实现的一个例子。

我有实体(其中一些实体在运行时使用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 query

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));
}

任何好的非平凡的例子或开源项目?

1 个答案:

答案 0 :(得分:0)

也许你可以看看我的LINQ to OpenCL翻译Brahma。 http://brahma.codeolex.com

它与我想要达到的目标非常相似。

希望这有帮助!