【问题标题】:LinQ query Simple Where clause and many filter criteriaLinQ 查询简单的 Where 子句和许多过滤条件
【发布时间】:2023-03-18 20:19:01
【问题描述】:

我需要过滤数据实体,但没有预定义的列,我必须过滤。

public class EventDocument
{
    public string ID1 { get; set; }
    public int ID2 { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Number { get; set; }
    public virtual ICollection<Event> Events { get; set; }
}

我创建了所有需要的属性: 搜索名字, 搜索姓氏, 搜索号码

现在我正在尝试通过用户输入的这些参数过滤 EventDocument。 如果用户在 SearchFirstName 中输入值,我的查询将如下所示:

var query = from b in DBContext.EventDocuments
                    where b.FirstName.Contains(SearchFirstName)
                    select b;

如果用户向 SearchFirstName 和 SearchLastName 输入值,我的查询将如下所示:

var query = from b in DBContext.EventDocuments
                        where b.FirstName.Contains(SearchFirstName) 
                        && b.LastName.Contains(SearchLastName)
                        select b;

如果我不知道如何构建查询 - 哪个归档用户将填写?也许他会为 SearchLastName 和 SearchNumber 输入值...

【问题讨论】:

    标签: c# .net linq ef-code-first entity-framework-6


    【解决方案1】:

    你可以这样做

    var query = DBContext.EventDocuments;
    
    if(!string.IsNullOrEmpty(SearchFirstName))
    {
        query = query.Where(x => x.FirstName.Contains(SearchFirstName));
    }
    if(!string.IsNullOrEmpty(SearchLastName))
    {
        query = query.Where(x => x.LastName.Contains(SearchLastName));
    }
    
    var result = query.ToList();
    

    并根据您需要的条件构建查询。

    【讨论】:

    • 谢谢,我没有正确完成我的问题。现在我正在做的就像你写的那样......但也在寻找如何不使用 lambdas 来解决这种情况......
    • 只是因为我很有趣。为什么不使用 lambda?
    • 实际上我正在尝试过滤大量记录并搜索最快的方式来做到这一点(也需要联合两个表......不幸运)我将能够定义搜索机制取决于关于用户将发布的内容
    • 如果您怀疑速度,我认为应该没有区别。也许Linq query or Lambda expression? 会有所帮助
    • @Sogaila:无论您使用方法还是查询语法,性能都没有差异。无论如何,查询语法将被转换为方法语法,因为它只是语法糖。
    【解决方案2】:

    谓词生成器是一种有效的方法。

    将以下代码放入静态 PredicateBuilder 类

     public static Expression<Func<T, bool>> ContainsPredicate<T>(string memberName, string searchValue)
            {
                var parameter = Expression.Parameter(typeof(T), "m");
                var member = Expression.PropertyOrField(parameter, memberName);
                var body = Expression.Call(
                    member,
                    "Contains",
                    Type.EmptyTypes, // no generic type arguments
                    Expression.Constant(searchValue)
                );
                return Expression.Lambda<Func<T, bool>>(body, parameter);
            }
    

    在你的cs文件中,

    var filterResults = PredicateBuilder.ContainsPredicate<Employee>(columnName, searchName);
    

    还有yourLinqQuery.Where(filterResults);

    供参考:Predicate Builder Details

    【讨论】:

    • 你能建议在这里写什么而不是 columnName:var filterResults = PredicateBuilder.ContainsPredicate(columnName, searchName);
    • 能否详细说明。我没能得到你。根据代码,您可以将 Employee 属性作为 columnName 传递。你期待这个吗?
    • 谢谢,我至少明白了,我将 columnName 作为字符串参数传递了。现在我将尝试传递参数列表和 memberNames
    【解决方案3】:

    【讨论】:

    • 考虑在你的答案中包含代码sn-ps,可以删除在线资源。
    【解决方案4】:
     var query = from eventDocument in DBContext.EventDocuments
                         where string.IsNullOrEmpty(firstName) || eventDocument.FirstName.Contains(firstName)
                         && string.IsNullOrEmpty(lastName) || eventDocument.LastName.Contains(lastName)
                         && string.IsNullOrEmpty(number) || eventDocument.Number.Contains(number)
                         select eventDocument;
    

    【讨论】:

      【解决方案5】:

      下面为我工作

        var query = from b in DBContext.EventDocuments
                          where (b.FirstName.Contains(SearchFirstName) && (!string.IsNullOrEmpty(SearchFirstName))
                          && (b.LastName.Contains(SearchLastName) && (!string.IsNullOrEmpty(SearchLastName))
                          && (b.SearchNumber.Contains(SearchNumber) && (!string.IsNullOrEmpty(SearchNumber))
                         select b;
      

      我在下面尝试过

      List<EventDocument> lsteventDoc = new List<EventDocument>() { 
                  new EventDocument{ID1 ="1", ID2=2, FirstName ="", LastName="Test", Number="1"},
                  new EventDocument{ID1 ="1", ID2=2, FirstName ="test", LastName="Test", Number="1"},
                  new EventDocument{ID1 ="1", ID2=2, FirstName ="", LastName="", Number="1"},
              };
              string SearchFirstName = "test";
              string SearchLastName="Test";
              string SearchNumber="1";
              var query = from b in lsteventDoc
                          where (b.FirstName.Contains(SearchFirstName) && (!string.IsNullOrEmpty(SearchFirstName)))
                          && (b.LastName.Contains(SearchLastName) && (!string.IsNullOrEmpty(SearchLastName)))
                          && (b.Number.Contains(SearchNumber) && (!string.IsNullOrEmpty(SearchNumber)))
                         select b;
      

      【讨论】:

      • 你好。如果用户只输入 SearchFirstName 会怎样?
      【解决方案6】:
      var query = from b in DBContext.EventDocuments
          where (b.FirstName.Contains(SearchFirstName) || SearchFirstName == "") 
          && (b.LastName.Contains(SearchLastName) || SearchLastName == "")
          && (b.Number.Contains(SearchNumber) || SearchNumber == "")
      select b;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-12-08
        • 2015-07-07
        • 1970-01-01
        • 1970-01-01
        • 2012-04-20
        • 2015-04-10
        • 1970-01-01
        相关资源
        最近更新 更多