【问题标题】:C# search using a LINQ query with child recordsC# 使用带有子记录的 LINQ 查询进行搜索
【发布时间】:2019-01-25 10:19:07
【问题描述】:

我有一个 Person 和 PersonType 对象,其中一个 Person 有一对多的 PersonType。 PersonType 可以是 Accountant、Consultant 等。

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

PersonType 表具有以下列: '名字' | '描述'

我在 C# 中使用 LINQ 创建了一个搜索机制,但问题是由于 LINQ 约束问题,我得到了错误的结果。假设我们有两条 Person 记录,其中第一条记录是 Consultant,另一条记录是 Consultant 和 Accountant,这意味着它必须是子对象。

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

假设我的搜索文本是“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;
}

【问题讨论】:

  • 早上的咖啡开始了。我只是在表达式的末尾添加了一个 Distinct() 语句。尘埃落定。 :)

标签: entity-framework linq


【解决方案1】:

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

只查询你需要的实体,除了where之外什么都不做。

您需要PersonViewModels。通过加入PersonTypes(from - from 是GroupJoin),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】:

    你可以得到如下结果

    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();
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-27
        • 1970-01-01
        相关资源
        最近更新 更多