使用带有子记录的LINQ查询进行C#搜索

时间:2019-01-25 10:19:07

标签: entity-framework linq

我有一个Person和PersonType对象,其中一个Person具有一对多的PersonType。 PersonType可以是会计师,顾问等。

人员表具有以下列: '名字'| '姓氏'| '电子邮件'| “电话号码”

PersonType表具有以下列: '名称'| '说明'

我已经在C#中使用LINQ创建了搜索机制,但是问题是由于LINQ约束问题而导致得到错误的结果。假设我们有两个“个人”记录,其中第一个记录是“顾问”,另一个记录是“顾问”和“会计师”,这意味着它必须针对子对象。

注意。我的搜索不区分大小写。

假设我的搜索文字是“ co”。那我不希望结果是3条记录。现在,由于会计的“ co”和第二人的顾问的两次匹配,它返回了第一人称和第二人称的两个实例。

我当然可以浏览结果并过滤出重复项,但是最好只查询一次。

非常感谢您的输入。

这是Linq:

private IList<PersonViewModel> SearchAll(string searchCriteria)
{
   var result = System.Web.HttpContext.Current.Session["Persons"] as IList<PersonViewModel>;

    if (result != null)
    {
        var v = (from a in result
                 from b in a.PersonTypes
                    where
                            a.FirstName.CaseInsensitiveContains(searchCriteria) ||
                            a.LastName.CaseInsensitiveContains(searchCriteria) ||
                            a.Email.CaseInsensitiveContains(searchCriteria) ||
                            a.PhoneNumber.CaseInsensitiveContains(searchCriteria) ||
                            b.Name.CaseInsensitiveContains(searchCriteria)
                 select a);

        return v.ToList();
    }

    return result;
}

3 个答案:

答案 0 :(得分:1)

您可以得到如下结果

var v=result?.Where(p=>p.PersonTypes.Select(t=>t.Name).Contains(searchCriteria)    ||
                            p.FirstName.CaseInsensitiveContains(searchCriteria)   ||
                            p.LastName.CaseInsensitiveContains(searchCriteria)    ||
                            p.Email.CaseInsensitiveContains(searchCriteria)       ||
                            p.PhoneNumber.CaseInsensitiveContains(searchCriteria) ||)?.ToList();

答案 1 :(得分:1)

一种小策略可能对查询和搜索条件的问题很有帮助:

仅查询您需要的实体,除了where之外什么也不做。

您需要PersonViewModel个。通过加入PersonTypesfrom - fromGroupJoin),PersonTypes也可以访问最终结果。因此,如果仅查询所需的实体,则应该只有一个,from

var v = from a in result

现在where应该是什么? PersonViewModel的条件很明确,但是PersonTypes呢? 用简单的语言定义,至少其中一个PersonTypes包含“ co” 。在LINQ中等于:

var v = from a in result
    where a.FirstName.CaseInsensitiveContains(searchCriteria)
       || a.LastName.CaseInsensitiveContains(searchCriteria)
       || a.Email.CaseInsensitiveContains(searchCriteria)
       || a.PhoneNumber.CaseInsensitiveContains(searchCriteria)
       || a.PersonTypes.Any(pt => pt.Name.CaseInsensitiveContains(searchCriteria));

现在,您不需要Distinct,因为没有join可以重复结果。

答案 2 :(得分:0)

萨拉姆 我认为您可以这样做

v.GroupBy(person => person.id)
  .Select(g => g.First())
  .ToList();