简体   繁体   English

具有可选字段和值的ASP.NET MVC查询

[英]ASP.NET MVC query with optional field and value

What I'm trying to do is provide a generic search capability on a table. 我正在尝试做的是在表上提供通用搜索功能。 So the user is presented with all data in a table, they enter some text to filter on, and voila, the table is now filtered on all results that match that entry. 因此,向用户显示了表中的所有数据,他们输入了一些要过滤的文本,瞧,现在,表在所有与该条目匹配的结果上进行了过滤。

I have this working with a single field: 我有一个单一领域的工作:

public ActionResult Index(string user_name)
{

    var dataContext = new PurchaseOrderDataContext();

    var orders = from o in dataContext.purchase_orders
                 where o.approved_by.display_name.StartsWith(user_name ?? "")
                 select o;

    if (Request.IsAjaxRequest())
    {
        return PartialView("list", orders);
    }
    else
    {
        return View(orders);
    }
}

But what I'm looking for is the ability for them to have a dropdown that allows them to pass in the field that they want to filter on. 但是我正在寻找的是让他们具有下拉菜单的功能,使他们能够传递要过滤的字段。 It would like something like this: 它想要这样的东西:

public ActionResult Index(string field, string query_value)
{

    var dataContext = new PurchaseOrderDataContext();

    var orders = from o in dataContext.purchase_orders
                 where o["field"].StartsWith(query_value ?? "")
                 select o;

    if (Request.IsAjaxRequest())
    {
        return PartialView("list", orders);
    }
    else
    {
        return View(orders);
    }
}

...Except that the o["field"] is just my silly guess at syntax (which doesn't work). ...除了o["field"]只是我对语法的愚蠢猜测(无效)。

I guess I'm just confused because although I'm using this nice class-ified data model, I sometimes want to explicitly refer to the columns by name. 我想我只是感到困惑,因为尽管我使用的是这种很好的分类数据模型,但有时我还是想按名称显式地引用列。

How would I go about doing this? 我将如何去做呢?

My apologies if this is obvious... 如果这很明显,我表示歉意...

Edit: I think I'm going to leave this open for now to see if there's a neater, less hack-ish feeling solution than suggested below. 编辑:我想我现在暂时不公开此内容,以查看是否有一种比下面建议的更整洁,更不合算的感觉解决方案。 Thanks! 谢谢!

The only simple (depends on your definition of "simple" I guess) way to do this would be to use the Dynamic Linq API. 做到这一点的唯一简单方法(取决于我对“简单”的定义)将使用Dynamic Linq API。 See here: 看这里:

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

The way I would do this is with a switch statement: 我这样做的方法是使用switch语句:

var orders = dataContext.purchase_orders;

if(!string.IsNullOrEmpty(query_value))
{
    switch(field)
    {
        case "firstname":
            orders = orders.Where(x => x.FirstName.StartsWith(query_value));
            return;
        case "company":
            orders = orders.Where(x => x.Company.StartsWith(query_value));
            return;
        // etc.
    }
}

This also allows you to validate field . 这也使您可以验证field

The main reason why you can't just put in the field name as the property name of your class is because Linq builds an expression tree. 之所以不能只将字段名称作为类的属性名称,是因为Linq构建了一个表达式树。

Now what you can do is split up how you're building your expression tree by doing. 现在,您可以做的是拆分如何构建表达式树。

var orders = from o in dataContext.purchase_orders
                 select o;

if (!string.IsNullOrEmpty(user_name)) {
     orders = orders.Where(x => x.StartsWith(user_name);
}

And just add more if statements.... ugh... Yeah it's definitely not pretty, and someone can probably make it look a lot better by making a IDictionary<string, Func<Expression, string>> instead of a bunch of if statements, but it still feels like a hack. 并添加更多的if语句....嗯...绝对不是很漂亮,有人可以通过使IDictionary <string,Func <Expression,string >>而不是if来使它看起来更好。声明,但仍然感觉像是骇客。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM