【问题标题】:Problems implementing a search filter using LINQ使用 LINQ 实现搜索过滤器的问题
【发布时间】:2017-03-30 12:59:07
【问题描述】:

我正在尝试在我的 ASP.Net 应用程序中使用 LINQ 实现搜索过滤器。

但是我遇到了问题。这是我的代码:

var result = (from x in db.ContactSet
    select new Models.Contact
    {
        AccountId = x.AccountId,
        FirstName = x.FirstName,
        LastName = x.LastName,
        FullName = x.FullName,
        JobTitle = x.JobTitle,
        ParentCustomerId = x.ParentCustomerId,
        EMailAddress1 = x.EMailAddress1,
        Telephone1 = x.Telephone1,
        MobilePhone = x.MobilePhone,
        Fax = x.Fax,
        GenderCode = x.GenderCode,
        BirthDate = x.BirthDate
    }); //? Gets all rows

result = result
    .Where(x =>
        x.FirstName.Contains(model.searchPhrase) ||
        x.LastName.Contains(model.searchPhrase)); //? Search Filter

Gets all rows 代码可以完美地从我的数据库中获取所有行。但是我对代码的Search Filter 部分有疑问。

model.searchPhrase 是一个可以为空的字符串。

每次我运行 Search Filter 时都没有返回任何内容(无论输入是什么。

调试后我注意到在该代码块运行后我得到以下Exception Error

静态成员:“NotSupportedException”是一种类型,在给定上下文中无效。 非公共成员:“new System.Linq.SystemCore_EnumerableDebugView(result).items”是“System.NotSupportedException”类型的异常

知道这里有什么问题吗?

【问题讨论】:

  • 你看到这个答案了吗? stackoverflow.com/a/19791382/728795
  • 你的 "gets all rows" 只是一个查询,你没有执行它。因此,当然以后会提出任何异常,例如在您的调试器中。您甚至没有提到 linq 提供程序,它是 Linq-To-Entities 吗?首先检查var list = result.ToList() 是否有效。
  • }); //? Gets all rows改成}).ToList(); //? Gets all rows来执行查询,看看这里是否真的出现了错误。您的搜索过滤器对我来说看起来不错。为什么不将两者结合起来并避免首先获取所有行?
  • 尝试将Contains 的顺序更改为model.searchPhrase.Contains(x.FirstName)LastName 的顺序相同

标签: c# asp.net linq


【解决方案1】:

我编写了一个库来帮助解决这个问题,并使构建过滤条件查询变得更加容易。您可以在此处从 NuGet 获取包:https://www.nuget.org/packages/LinqConditionalExtensions

你的代码可以改写为:

var hasFilter = !string.IsNullOrWhiteSpace(model.searchPhrase);

var result = db.ContactSet
    .WhereIf(hasFilter, x => x.FirstName.Contains(model.searchPhrase) || x.LastName.Contains(model.searchPhrase))
    .Select(x => new Models.Contact
    {
        AccountId = x.AccountId,
        FirstName = x.FirstName,
        LastName = x.LastName,
        FullName = x.FullName,
        JobTitle = x.JobTitle,
        ParentCustomerId = x.ParentCustomerId,
        EMailAddress1 = x.EMailAddress1,
        Telephone1 = x.Telephone1,
        MobilePhone = x.MobilePhone,
        Fax = x.Fax,
        GenderCode = x.GenderCode,
        BirthDate = x.BirthDate
    });

WhereIf() 方法仅在条件为真时应用过滤器。在这种情况下,如果您的模型的搜索短语不是空值或空格。

您可以在此处阅读更多信息:https://github.com/xKloc/LinqConditionalExtensions

【讨论】:

    【解决方案2】:

    model.searchPhrase 如他所写,是一个可以为空的字符串。您不能在 LINQ Query 中将数据类型可为空的变量与数据类型(字符串变量)进行比较。所以,它正在抛出异常。

    使用以下代码。它对我有用

    string SearchValue="";
    try
    {SearchValue=model.searchPhrase.Tostring();}catch{}
    
    result = result.Where(x => x.FirstName.Contains(SearchValue) ||
            x.LastName.Contains(SearchValue)).ToList();
    

    【讨论】:

    • 你只是在隐藏异常 0.o
    • @FCin ,model.searchPhrase 是他写的可以为空的字符串。您无法在 LINQ Query 中将数据类型(字符串?变量)与数据类型(字符串变量)进行比较。所以,它正在抛出异常。
    • 但是隐藏异常并不是最好的解决方案。例外是昂贵的,而且它们看起来并不讨人喜欢。
    • @FCin,您应该将此建议告知 Microsoft,以便他们在实体框架中进行更改,然后允许可空变量与字符串进行比较。
    猜你喜欢
    • 2019-09-19
    • 2013-05-24
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    相关资源
    最近更新 更多