首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取Predicate<T>属性信息

获取Predicate<T>属性信息
EN

Stack Overflow用户
提问于 2010-03-09 21:52:56
回答 3查看 1.4K关注 0票数 3

我有一个类似于下面的界面:

代码语言:javascript
复制
public IEnumerable<IDocument> Search(Predicate<IDocument> predicate) { ... }

其中IDocument如下所示:

代码语言:javascript
复制
public interface IDocument 
{
    string Id {get; set;}
    string Title {get; set;}
    ...
}

我将要实现一个文档提供程序,在该提供程序中,我必须分解谓词的内容并提取属性,以便为文档数据库生成SQL字符串,而我们目前没有到该文档数据库的OR/M映射。例如:我想知道用户是按ID搜索还是按标题搜索,这样我就知道我是否可以按ID搜索或必须对标题执行LIKE搜索。

我一直在大量使用LINQ,但这是我第一次坐在管道的另一端……我已经阅读了一些关于表达式、树和反射的内容,但这些部分还没有到位。如何(如果?)我是否可以分解/反射谓词,以便获得可以连接到SQL字符串中的参数列表?我正在寻找类似于这个草图的东西:

代码语言:javascript
复制
public IEnumerable<IDocument> Search(Predicate<IDocument> predicate) 
{ 
    string id = DoSomeMagic(predicate, "Id");
    string title = DoSomeMagic(predicate, "Title");
    if (!string.isNullOrEmpty(id))
       ...make ID search
    else
       ...search by title
}

免责声明:提供者是为一个内部遗留系统准备在今年秋天进行替换,这使得内联SQL成为一个合适的选择;o)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-03-09 22:13:40

你不能轻易地反省这个谓词。也许您应该考虑将您的设计更改为更特别的谓词类型,即更具体的谓词接口:

代码语言:javascript
复制
    public interface IDocument 
    {
        string Id {get; set;}
        string Title {get; set;}
    }
    public class SearchCriteria
    {
        public Nullable<int> Id;
        public string Title;
    }
    public IEnumerable<IDocument> Search(SearchCriteria predicate)
    {
        if (predicate.Id.HasValue)
            //...make ID search
        else if (!string.IsNullOrEmpty(predicate.Title))
            //...search by title
        else
            // other kind of search
    }

用属性替换公共字段,将搜索逻辑放在SearchCriteria (例如.GetResult()或.GetSQLQuery())中,假设您知道所有可用的搜索条件,这可能适合您的系统。

票数 1
EN

Stack Overflow用户

发布于 2010-03-09 22:00:15

您不能使用谓词或委托来做到这一点。它们是经过编译的,不可能得到关于它做了什么的信息。为此,您确实需要Expression树,但是自己解析可能会很困难。你最好使用O/RM工具。

例如,当您将表达式与LINQ to SQL一起使用时,构建您的搜索方法将是轻而易举的:

代码语言:javascript
复制
public IEnumerable<Document> Search(
    Expression<Func<Document, bool>> predicate) 
{
    using (db = new DocumentDataContext())
    {
        return db.Documents.Where(predicate).ToArray();
    }
}
票数 3
EN

Stack Overflow用户

发布于 2010-03-09 22:31:03

您需要将您的方法声明为接受Expression>。这个表达式可以内省(尽管可以有很多不同的东西)。

尝试在LinqPad中运行以下代码(LinqPad提供了转储扩展方法,可以很好地将表达式可视化)

代码语言:javascript
复制
void Main()
{
    show(x=>x.Length==5);
}

void show(Expression<Predicate<string>> e){
    e.Dump();
}

您可以通过首先调用Compile来执行表达式

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2409442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档