简体   繁体   English

如何使用传递的字符串参数从控制器编写MVC实体框架选择查询?

[英]How do I write an MVC Entity Framework select query from the controller using passed string arguments?

I created a search tool in MVC. 我在MVC中创建了一个搜索工具。 The user types the searchTerm string into a search box and selects options for the search from 2 dropdown select lists. 用户在搜索框中键入searchTerm字符串,然后从2个下拉选择列表中选择搜索选项。 From the first list the user selects "Fuzzy" or "Literal" for the searchType, and from the second list the user can select a specific field to search, specField. 用户从第一个列表中为searchType选择“ Fuzzy”或“ Literal”,从第二个列表中,用户可以选择要搜索的特定字段specField。 The 3 string values are passed to the controller once the search button is clicked. 单击搜索按钮后,会将3个字符串值传递给控制器​​。
I am trying to write an "if" statement that queries the Entity Framework DB model based on these 3 string values passed into the controller. 我正在尝试编写一个“ if”语句,该语句根据传递给控制器​​的这3个字符串值查询Entity Framework DB模型。 How do I write queries that use these values? 如何编写使用这些值的查询? This is what I have. 这就是我所拥有的。 I know the queries aren't written correctly: 我知道查询的书写方式不正确:

 Public PartialViewResult _Search(string searchTerm, string specField, string searchType)
 {
      //This works to populate the table with the entire DB 
      _db = new IntegrationDBEntities();
      var request = (from r in _db.Requests
                     select r).ToList();

     //These two are not correct and I need help writing these
     if (searchType == "Fuzzy" && searchTerm != "" && specField != "None")
     {
          request = (from r in _db.Requests
                          where r.(specField).Contains(searchTerm)
                          select r).ToList();
     }
     if (searchType == "Literal" && searchTerm != "" && specField == "None")
     {
          request = (from r in _db.Requests
                         where r.Equals(searchTerm)
                         select r).ToList();
     }
     ViewData.Model = request;
     Return partialView();
 }  

I am not 100% sure about how you Request object looks like, but I would use PredicateBuilder . 我不确定您的Request对象是什么样子,但我会100%使用PredicateBuilder Here is an example of what your search function could look like. 这是您的搜索功能外观示例。

IQueryable<Request> SearchRequests (string searchTerm, string specField, string searchType)
{
    var predicate = PredicateBuilder.False<Request>();

    //These two are not correct and I need help writing these
    if (searchType == "Fuzzy" && searchTerm != "" && specField != "None")
    {
        predicate = predicate.Or (r => r.(specField).Contains(searchTerm));
    }
    if (searchType == "Literal" && searchTerm != "" && specField == "None")
    {
        predicate = predicate.Or (r => r.Equals(searchTerm));
    }

    return new IntegrationDBEntities()
                  .Requests
                  .AsExpandable()
                  .Where(predicate);
}

Then your method could look like this: 然后您的方法可能如下所示:

Public PartialViewResult _Search(string searchTerm, string specField, string searchType)
 {
     ViewData.Model = SearchRequests(searchTerm, specField, searchType).ToList();
     Return partialView();
 } 

UPDATE : I added working example from LinqPad. 更新 :我从LinqPad添加了工作示例。 You will need to modify it slightly to get it to work for you with EntityFramework . 您将需要对其稍加修改,以使其与EntityFramework

void Main()
{
    var results = SearchRequests("Fuzzy", "later").ToList();
    results.Dump();

    var results2 = SearchRequests("Literal", "Test me now").ToList();
    results2.Dump();
}

// Define other methods and classes here
public class Request
{
    public int Id {get;set;}
    public string SearchTerm {get;set;}
}

public IQueryable<Request> LoadData()
{
    var list = new List<Request>();
    list.Add(new Request {Id = 1, SearchTerm = "Test me now"});
    list.Add(new Request {Id = 2, SearchTerm = "Test me later"});
    list.Add(new Request {Id = 3, SearchTerm = "Test me maybe"});
    list.Add(new Request {Id = 4, SearchTerm = "Test me now"});
    list.Add(new Request {Id = 5, SearchTerm = "Test me later or never"});
    list.Add(new Request {Id = 6, SearchTerm = "Test me maybe or today"});

    return list.AsQueryable();
}

public IQueryable<Request> SearchRequests (string searchType, string searchTerm)
{
    var data = LoadData();
    var predicate = PredicateBuilder.False<Request>();
    //These two are not correct and I need help writing these
    if (searchType == "Fuzzy")
    {
        predicate = predicate.Or(r => r.SearchTerm.Contains(searchTerm));
    }
    if (searchType == "Literal")
    {
        predicate = predicate.Or (r => r.SearchTerm.Equals(searchTerm));
    }

    return data.Where(predicate);
}

public static class PredicateBuilder
{
    public static Expression<Func<T, bool>> True<T> ()  { return f => true;  }
    public static Expression<Func<T, bool>> False<T> () { return f => false; }

    public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
                                                        Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
        return Expression.Lambda<Func<T, bool>>
            (Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
    }

    public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
                                                        Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
        return Expression.Lambda<Func<T, bool>>
            (Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
    }
}

Results for first search: 首次搜索结果:

Id  SearchTerm
2   Test me later
5   Test me later or never

Results for second search: 第二次搜索结果:

Id  SearchTerm
1   Test me now
4   Test me now

Hope this works with no errors: 希望这没有错误:

ParameterExpression pe = Expression.Parameter(typeof(Request), "Request");
Expression property = Expression.Property(pe, specField);
Expression predicate = null;
Expression srch = Expression.Constant(searchTerm, typeof(string));
if(searchType == "Fuzzy")
{
    MethodInfo contains = typeof(string).GetMethod("Contains", new Type[] { typeof(string) });
    predicate = Expression.Call(property, contains, srch);
}
else
{
    predicate = Expression.Equal(property, srch);
}

MethodCallExpression where = Expression.Call(
    typeof(Queryable),
    "Where",
    new Type[] { _db.Requests.ElementType },
    _db.Requests.Expression,
    Expression.Lambda<Func<Request, bool>>(predicate, new ParameterExpression[] { pe }));

IQueryable<Request> result = _db.Requests.Provider.CreateQuery<Request>(where);

var list = result.ToList();

Let me know if you have any trouble 让我知道你是否有任何麻烦

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

相关问题 如何编写这样的查询SELECT * FROM TABLE WHERE COLUMN LIKE&#39;%“ BLABLA”:[%“ BLABLA1”%]%&#39;使用实体框架 - How to write such a query SELECT * FROM TABLE WHERE COLUMN LIKE '%“BLABLA”:[%“BLABLA1”%]%' using Entity Framework 如何在实体框架中编写此查询 - How do i write this query in entity-framework 如何在此Entity Framework IQueryable查询中抽象出select? - How do I abstract out the select in this Entity Framework IQueryable query? 我应该如何编写此实体框架查询? - How should I write this Entity Framework query? 如何在MVC 4中使用Entity Framework从C#代码部分使用SQL函数 - How do I use a SQL function from C# code section using Entity Framework in MVC 4 如何在 mvc 控制器中写入数据? - How do I write data in mvc controller? 我如何从下拉列表中选择值到模式或控制器MVC - how do i select value from dropdownlist to mode or to controller mvc 如何在ASP.Net MVC实体框架的帐户控制器中传递来自登录方法的ID? - How can I pass the Id from Login method in Account Controller in ASP.Net MVC Entity Framework? 我是否必须进行选择查询才能在Entity Framework中创建关系? - Do I have to make a select query to create a relationship in Entity Framework? 使用实体框架创建MVC4-Controller - Creating a MVC4-Controller using Entity Framework
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM