使用Linq动态添加条件连接

时间:2010-08-20 18:09:56

标签: asp.net linq-to-sql join

我有一个基本的搜索控件,根据下拉列表提供的预定义搜索/过滤条件列出CRM中的公司。每个DropDown的默认选择为“ALL”,否则用户选择特定的项目。我希望能够根据选择动态构建Linq查询。在5个选择器中,它们提供了我可以与Company表匹配的值,但是两个选择器(如果选择其中一个或两个)将需要连接或连接,否则不应再对基础结果集采取任何操作。我希望这是有道理的。

我不确定如何有效地做到这一点。这是我的代码:

private void Search()
{
    EnergyPubsCRMDataContext dc = new EnergyPubsCRMDataContext();

    var results = (from c in dc.Companies
                   select c);


    //only create the join if the selected index > 0
    if (ddlIndustry.SelectedIndex > 0)
    {
        //A company can be in 1 or more industries, thus here I want to join
        //with the CompanyIndustry table and have a WHERE clause to match on the ddlIndustry.SelectedValue
    }

    //only create the join if the selected index > 0
    if (ddlServices.SelectedIndex > 0)
    {
        //A company can offer 1 or more services. Here I want to join to the CompanyService table
        //on the CompanyID and have a WHERE clause to match the ddlServices.SelectedValue
    }        

    //These work OK to shape the overal query further (they don't need joins)
    if (ddlCountry.SelectedIndex > 0)
        results = results.Where(c => c.CountryID == Convert.ToInt32(ddlCountry.SelectedValue));

    if (ddlStateRegion.SelectedIndex > 0)
        results = results.Where(c => c.StateRegionID == Convert.ToInt32(ddlStateRegion.SelectedValue));

    if (ddlAccountManagers.SelectedIndex > 0)
    {
        Guid g = new Guid(ddlAccountManagers.SelectedValue);
        results = results.Where(c => c.UserId == g);
    }

    results = results.OrderBy(c => c.CompanyName);

    //Bind to Grid....        
}

2 个答案:

答案 0 :(得分:0)

if (ddlIndustry.SelectedIndex > 0)
{
    //A company can be in 1 or more industries, thus here I want to join
    //with the CompanyIndustry table and have a WHERE clause to match on the ddlIndustry.SelectedValue
    results = results.Where(c => c.CompanyIndustry.IndustryID == ddlIndustry.SelectedValue);
}

假设您的数据库/ DBML中有正确的外键。

这将隐式生成连接。

答案 1 :(得分:0)

我有非常类似的问题,没有我可以利用的外键。 我的解决方案将转化为以下内容:

results = results
  .Join(dc.CompanyIndustry, c => c.CompanyID, ci => ci.CompanyID, (c, ci) => new { c, ci.IndustryID })
  .Where (a => a.IndustryID == ddlIndustry.SelectedValue)
  .Select(a => a.c);

基本上:

1)首先我们创建一个连接,其投影为我们提供了IndustryID(加入)

2)我们根据IndustryID(其中)过滤

3)我们返回原始匿名类型,以便我们可以修改原始查询(选择)