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 来查询项目。
问题:我不能Post.Text在 Where 子句中使用。
解决方案:创建自己的扩展方法,将 lambda 表达式转换为另一种格式。

例如查询

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

有什么好的不平凡的例子或开源项目?

4

1 回答 1

0

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

它所做的事情与您想要实现的目标非常相似。

希望这可以帮助!

于 2012-05-30T12:43:28.547 回答