【问题标题】:LINQ PredicateBuilder not work in my dynamic searchLINQ PredicateBuilder 在我的动态搜索中不起作用
【发布时间】:2016-08-22 07:40:01
【问题描述】:

我的数据库中有一个书本表,我的 edmx 中有一个名为 vwShared 的书本视图。我想使用运算符创建动态搜索,供用户查找书籍。我有 2 个 SearchColumns 下拉列表,其中包含“标题、作者、出版年份、主题”。我有 2 个 SearchType 下拉列表,其中包含“StartsWith、Contains、EndsWith、Equals”。我有另一个下拉列表包含“AND,OR”来组合 2 个搜索结果。以下是我的代码。

var predicate = PredicateBuilder.True<DataLayer.vwShared>();

if (joinOperator == "AND")
{
if (SearchColumn1 == "Title" && SearchType1 == "Contains")
predicate = predicate.And(e1 => e1.Title.Contains(txtSearch1.Text));
if (SearchColumn2 == "Authors" && SearchType2 == "Contains")
predicate = predicate.And(e1 => e1.Authors.Contains(txtSearch2.Text));
}
else if (joinOperator == "OR")
{
if (SearchColumn1 == "Title" && SearchType1 == "Contains")
predicate = predicate.Or(e1 => e1.Title.Contains(txtSearch1.Text));
if (SearchColumn2 == "Authors" && SearchType2 == "Contains")
predicate = predicate.Or(e1 => e1.Authors.Contains(txtSearch2.Text));
}

List<DataLayer.vwShared> bookList= new DataLayer.Solib_DMREntities().SP_SharedData_GetAll("AllLocal").ToList<DataLayer.vwShared>();

var bookList= from books in bookList.AsQueryable().Where(predicate)
                select books ;

gvBooks.DataSource = bookList.ToList();
gvBooks.DataBind();

上面的代码没有返回正确的结果。有什么不对。 ? 以下是我的参考网站。 http://www.albahari.com/nutshell/predicatebuilder.aspx 请给我建议。

谢谢。

【问题讨论】:

    标签: linq predicatebuilder


    【解决方案1】:

    回答您的具体问题。问题出在构建OR 谓词的分支上,在这种情况下你应该从PredicateBuilder.False 开始,否则根本不会过滤(正如我们从学校知道的,true or something 总是true :)

    // ...
    else if (joinOperator == "OR")
    {
        predicate = PredicateBuilder.False<DataLayer.vwShared>();
        // ...
    }
    // ...
    

    【讨论】:

      【解决方案2】:

      第 1 步:模型

      public class Person
      {
          public int PersonId { get; set; }
          public int? Age { get; set; }
          public string FirstName { get; set; }
          public string LastName { get; set; }
          public int? Salary { get; set; }
      
      }
      
      
      public class PersonDBContext : DbContext
      {
          public virtual DbSet<Person> People { get; set; }
      }
      

      第 2 步:控制器

      public class PersonController
      {
      
          PersonDBContext db = new PersonDBContext();
      
          public void Add(Person person)
          {
              db.People.Add(person);
              db.SaveChanges();
          }
          public List<Person> GetAll()
          {
              return db.People.ToList();
          }
      
          public List<Person> GetByPredicateValue(Expression<Func<Person, bool>> predicate)
          {
              if (predicate != null)
                  return db.People.Where(predicate.Compile()).ToList();
              else
                  return null;
          }
      
          public List<Person> GetByPredicateAndPersonListValue(List<Person> PeopleList,Expression<Func<Person, bool>> predicate)
          {
              if (predicate != null)
                  return PeopleList.Where(predicate.Compile()).ToList();
              else
                  return null;
          }
      
      
      }
      

      第 3 步:后面的代码

      public partial class MainWindow : Window
          {
              PersonController pc;
              public static List<Person> PeopleFilterList = null;
              public static string CurrentColumn = null;
              public MainWindow()
              {
      
                  pc = new PersonController();        
                  InitializeComponent();
                  grid.ItemsSource = pc.GetAll();
                  grid.PreviewMouseDown += grid_PreviewMouseDown;
              }
      
              void grid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
              {
                  TableViewHitInfo hi = ((TableView)grid.View).CalcHitInfo(e.OriginalSource as DependencyObject);
                  if (hi == null) return;
                  if (hi.HitTest == TableViewHitTest.ColumnHeader || hi.HitTest == TableViewHitTest.ColumnHeaderFilterButton)
                  {
                      grid.UnselectAll();
                      GridColumn currentColumn = ((DevExpress.Xpf.Grid.GridViewHitInfoBase)(hi)).Column;
                      CurrentColumn = currentColumn.FieldName;
                      (grid.View as TableView).SelectCells(0, currentColumn, grid.VisibleRowCount - 1, currentColumn);            
                  }
              }
      
              Expression<Func<Person, bool>> _result=null;
              string str="";
              private void IdForm_ButtonClicked(object sender, IdentityUpdateEventArgs e)
              {
                  _result = e.FirstName;
              }
      
              public MainWindow(Expression<Func<Person, bool>> result)
              {
                  Window1 f = new Window1();
                  f.IdentityUpdated += new Window1.IdentityUpdateHandler(IdForm_ButtonClicked);
                  pc = new PersonController();
                  InitializeComponent();                 
                  _result = result;
                  if (PeopleFilterList != null)
                      PeopleFilterList = pc.GetByPredicateAndPersonListValue(PeopleFilterList,_result).ToList();
                  else
                      PeopleFilterList = pc.GetByPredicateValue(_result).ToList();
                  grid.ItemsSource = PeopleFilterList;
                  grid.PreviewMouseDown += grid_PreviewMouseDown;
              }
      
      
              private void Button_Click(object sender, RoutedEventArgs e)
              {
                  Window1 w1 = new Window1(CurrentColumn);
                  w1.Show();
      
              }
      
          }
      

      第 4 步:过滤后面的代码

       public partial class Window1 : Window
          {
              public delegate void IdentityUpdateHandler(object sender, IdentityUpdateEventArgs e);
              public event IdentityUpdateHandler IdentityUpdated;
      
      
              string _currentColumn = null;
              public Window1()
              {
                  InitializeComponent();
              }
      
              public Window1(string currentColumn)
              {
                  _currentColumn = currentColumn;
                  InitializeComponent();
              }
      
              public static Expression<Func<Person, bool>> predicateValue;
              IdentityUpdateEventArgs args;
              private void Button_Click(object sender, RoutedEventArgs e)
              {
      
                  string operatorName = "";
      
      
                  if (!String.IsNullOrEmpty(txtSmaller.Text.Trim()))
                      operatorName = txtSmaller.Name;
                  else if (!String.IsNullOrEmpty(txtElder.Text.Trim()))
                      operatorName = txtElder.Name;
                  else if (!String.IsNullOrEmpty(txtContains.Text.Trim()))
                      operatorName = txtContains.Name;
                  else if (!String.IsNullOrEmpty(txtStartWith.Text.Trim()))
                      operatorName = txtStartWith.Name;
                  else if (!String.IsNullOrEmpty(txtEqual.Text.Trim()))
                      operatorName = txtEqual.Name;
                  else if (!String.IsNullOrEmpty(txtNotEqual.Text.Trim()))
                      operatorName = txtNotEqual.Name;
                  else if (!String.IsNullOrEmpty(txtSmallerOrEqual.Text.Trim()))
                      operatorName = txtSmallerOrEqual.Name;
                  else if (!String.IsNullOrEmpty(txtElderOrEqual.Text.Trim()))
                      operatorName = txtElderOrEqual.Name;
      
                  else if (!String.IsNullOrEmpty(txtSmallerThan.Text.Trim()) && !String.IsNullOrEmpty(txtBiggerThan.Text.Trim()))
                      operatorName = txtSmallerThan.Name;
      
      
                  switch (operatorName)
                  {
                      case "txtSmaller":          
                          predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) < Convert.ToInt32(txtSmaller.Text));
                          break;
      
                      case "txtElder":
                          predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) > Convert.ToInt32(txtElder.Text));
                          break;
      
                      case "txtSmallerOrEqual":
                          predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) <= Convert.ToInt32(txtSmallerOrEqual.Text));
                          break;
      
                      case "txtElderOrEqual":
                          predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) >= Convert.ToInt32(txtElderOrEqual.Text));
                          break;
      
                      case "txtEqual":
                          predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) == Convert.ToInt32(txtEqual.Text));
                          break;
      
                      case "txtNotEqual":
                          predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) != Convert.ToInt32(txtNotEqual.Text));
                          break;
      
                      case "txtSmallerThan":
                          predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) >= Convert.ToInt32(txtBiggerThan.Text)
                          && (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) <= Convert.ToInt32(txtSmallerThan.Text));
                          break;
      
                      case "txtStartWith":
                          predicateValue = (x => x.GetType().GetProperty(_currentColumn).GetValue(x, null).ToString().StartsWith(txtStartWith.Text));      
                          break;
      
                      case "txtContains":
                          predicateValue = (x => x.GetType().GetProperty(_currentColumn).GetValue(x,null).ToString().Contains(txtContains.Text));                    
                          break;                  
                  }
      
      
      
      
                  MainWindow mw = new MainWindow(predicateValue);
                  mw.Show();
                  this.Close();
              }
      
              void Window1_IdentityUpdated(object sender, IdentityUpdateEventArgs e)
              {
                  e = args;
              }
      
          }
      
          public class IdentityUpdateEventArgs : System.EventArgs
          {
              private Expression<Func<Person, bool>> mFirstName;
      
              public IdentityUpdateEventArgs(Expression<Func<Person, bool>> sFirstName)
              {
                  this.mFirstName = sFirstName;
              }
      
              public Expression<Func<Person, bool>> FirstName
              {
                  get
                  {
                      return mFirstName;
                  }
              }    
      
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-22
        • 1970-01-01
        • 2017-01-25
        • 2021-10-04
        • 2016-11-13
        • 1970-01-01
        相关资源
        最近更新 更多