【问题标题】:Search within navigation properties在导航属性中搜索
【发布时间】:2012-09-08 18:07:56
【问题描述】:

我使用 ASP.NET MVC 4 中的代码优先方法创建了我的应用程序。

我有三个实体。即“Company”、“Service”和“ServiceFeature”:

public class Company
{
    public int CompanyID { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public string Description { get; set; }

    public virtual Service SuppliedService { get; set; }

}

public class Service
{
    public int ServiceID { get; set; }

    [Required]
    public string Name { get; set; }

    public virtual ICollection<ServiceFeature> ServiceFeatures { get; set; }

}    

public class ServiceFeature
{
    public int ServiceFeatureID { get; set; }

    [Required]
    public string Name { get; set; }


}

我有一个搜索表单,它包含所有 ServiceFeature 的复选框。用户将选中复选框并获取提供服务的公司的结果以及选定的 ServiceFeatures。

我的服务获得了公司列表,如下所示,但我不知道如何在 where 子句中包含选定的 ServiceFeatures(带有 for 循环的动态 LINQ?)

var searchResults = _companyService.GetCompanies();

【问题讨论】:

    标签: asp.net-mvc linq ef-code-first


    【解决方案1】:

    假设您有一个包含所选功能 ID 的集合,称为 requested,并假设您希望公司提供包含所有所选功能的服务,例如,您可以这样做:

    var q = from c in searchResults
            let sf = c.SuppliedService.ServiceFeatures
                                      .Select(f => f.ServiceFeatureID)
                                      .Intersect(requested)
            where sf.Count() == requested.Count()
            select c;
    

    【讨论】:

      【解决方案2】:

      在类似的情况下,我更喜欢一种比使用Intersect 的 linq 查询更复杂的方法。 Intersect 可以产生带有深度嵌套的可怕查询,因为具有要相交的 Id 值的列表是由列表中每个 Id 的 SELECTUNION 命令构建的。当 Id 的数量较少时,这不是问题(我假设在您的情况下是这样),但如果数量较大,它可能会引发 SQL 异常。

      所以这是我更喜欢的:

      var q = context.Companies.AsQueryable();
      
      foreach(int i in featureIds)
      {
          int j = i; // prevent modified closure.
          q = q.Where(c => c.SuppliedService.ServiceFeatures.Any(f => f.Id == j));
      }
      
      var result = q.ToList();
      

      它使用许多WHERE EXISTS 子句构建一个查询。这可能非常有效,因为每个EXISTS 都会寻找(而不是扫描)ServiceFeature 的主索引。除此之外,INTERSECT 是隐含的DISTINCT

      嗯,只是想指出这一点。如前所述,在记录数量较少的情况下,您不会注意到任何差异。所以选择最适合你的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多