Добавить условное соединение динамически с Linq - PullRequest
0 голосов
/ 20 августа 2010

У меня есть базовый элемент управления поиском, который перечисляет компании из CRM в зависимости от предопределенных критериев поиска / фильтрации, предоставляемых раскрывающимися списками. По умолчанию выбрано «ВСЕ» для каждого DropDown, в противном случае пользователь выбирает определенный элемент (ы). Я хотел бы иметь возможность построить запрос 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 голосов
/ 27 апреля 2012

У меня была очень похожая проблема, и я не мог использовать внешние ключи. Мое решение будет выглядеть примерно так:

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) мы возвращаем исходный анонимный тип, чтобы мы могли изменить исходный запрос (выбрать)

0 голосов
/ 21 августа 2010
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 есть правильные внешние ключи.

Это создаст неявное соединение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...