несколько параметров поиска в нескольких объединенных таблицах с использованием LINQ в DBML - PullRequest
3 голосов
/ 14 марта 2019

Я хочу создать advanced multiple parameters search для веб-сайта.
Это моя схема DBML и ORM:
enter image description here В этом advanced multiple parameters search пользователь может осуществлять поиск по объектам с несколькими параметрами, такими как размер, этаж, город, цена и т. Д.
Это функция, которую я кодировал для обработки этой части.

 private DataTable linq_search_by_details()
    {
        myDBMLDataContext ctx = new myDBMLDataContext(address);
        var query = ctx.Estates.AsQueryable();
        query = query.Where(c => c.eshId == int.Parse(ddlEshape.SelectedValue.ToString()));
        query = query.Where(c => c.cityId == int.Parse(ddlcity.SelectedValue.ToString()));
        query = query.Where(c => c.ETId == int.Parse(ddlType.SelectedValue.ToString()));
        query = query.Where(c => c.dealingId == int.Parse(ddldeal.SelectedValue.ToString()));
        query = query.Where(c => c.deedId == int.Parse(ddldeed.SelectedValue.ToString()));
        if (!string.IsNullOrEmpty(txtPrepaymentFrom.Value.Trim()))
        {
            query = query.Where(c => int.Parse(c.prepayment) <= int.Parse(txtPrepaymentFrom.Value));
        }
        if (!string.IsNullOrEmpty(txtPrepaymentTo.Value.Trim()))
        {
            query = query.Where(c => int.Parse(c.prepayment) >= int.Parse(txtPrepaymentTo.Value));
        }
        if (!string.IsNullOrEmpty(txtPrepaymentFrom.Value.Trim()) && !string.IsNullOrEmpty(txtPrepaymentTo.Value.Trim()))
        {
            query = query.Where(c => int.Parse(c.prepayment) <= int.Parse(txtPrepaymentFrom.Value) && int.Parse(c.prepayment) >= int.Parse(txtPrepaymentTo.Value));
        }

        if (!string.IsNullOrEmpty(txtPriceFrom.Value.Trim()))
        {
            query = query.Where(c => int.Parse(c.price) <= int.Parse(txtPriceFrom.Value));
        }
        if (!string.IsNullOrEmpty(txtPriceTo.Value.Trim()))
        {
            query = query.Where(c => int.Parse(c.price) >= int.Parse(txtPriceTo.Value));
        }
        if (!string.IsNullOrEmpty(txtPriceFrom.Value.Trim()) && !string.IsNullOrEmpty(txtPriceTo.Value.Trim()))
        {
            query = query.Where(c => int.Parse(c.price) <= int.Parse(txtPriceFrom.Value) && int.Parse(c.price) >= int.Parse(txtPriceTo.Value));
        }

        if (!string.IsNullOrEmpty(txtFloor.Value.Trim()))
        {
            query = query.Where(c => c.eFloor == short.Parse(txtFloor.Value));
        }
        if (chbExchange.Checked)
        {
            query = query.Where(c => c.exchange == true);
        }

        var final = query.Select(c => new { c.esId,c.owId, c.City.cityName, c.EstateShape.eshName, c.EstateType.ETName, c.owner.owFname, c.owner.owLname, c.esSize, c.prepayment, c.price });
        return Special.LINQResultToDataTable(final.ToList());
}

Эта функция работает отлично, но теперь я хочу добавить несколько параметров из EstateEquipment и EstateFacility.
Как вы можете видеть в ORM, соотношение между Estate и EstateEquipment (также Estate и EstateFacility) составляет one to many.
Теперь я хочу, чтобы пользователь мог искать через Estate в cityId = 1, size around 400m, который имеет, например, eqId = 1 and 2 из EstateEquipment, а затем, например, fId = 1 and 2 из EstateFacility.

Вот как я пытался справиться с последней частью.

foreach (ListItem item in cblEquipment.Items)
{
    if (item.Selected)
    {
        eq = true;
    }
}
if(eq)
{
    var eqQuery = ctx.EstateEquipments.AsQueryable();
    foreach (ListItem item in cblEquipment.Items)
    {
        if (item.Selected)
        {
            eqQuery = eqQuery.Where(c => c.eqId == int.Parse(item.Value.ToString()));
        }
    }
    var eqFinal = eqQuery.Select(c => new { c.Estate.esId, c.Estate.owner.owId, c.Estate.City.cityName, c.Estate.EstateShape.eshName, c.Estate.EstateType.ETName, c.Estate.owner.owFname, c.Estate.owner.owLname, c.Estate.esSize, c.Estate.prepayment, c.Estate.price });
    DataTable dtEq = Special.LINQResultToDataTable(eqFinal.ToList());
    if(dtEq.Rows.Count>0)
    {
        this.Build_search(dtEq);
    }
    else
    {
        msg = "No record found";
        sysMsg.Attributes["class"] = "";
        sysMsg.Attributes["class"] = "alert alert-warning";
    }
}

Здесь я сначала проверяю, какое оборудование выбрано из списка. Затем расширил запрос в соответствии с выбранными пунктами. Но я не знаю, как объединить этот новый результат с последним результатом и даже EstateFacility результатом.
Спасибо за любую помощь.

1 Ответ

3 голосов
/ 20 марта 2019

Не имея возможности проверить мое решение из-за вашего довольно сложного случая, я надеюсь, что оно, по крайней мере, направит вас в правильном направлении.

Я бы сказал, попробуйте что-то вроде этого:

    if (cblEquipment.Items.Any(item => item.Selected))
    {
        var selectedEquipmentIds = cblEquipment.Items.Where(item => item.Selected).Select(item => int.Parse(item.Value.ToString()));
        query = query.Where(c => ctx.EstateEquipments.Any(eq => eq.esId == c.esId && selectedEquipmentIds.Contains(eq.eqId)));
    }

Это идет в вашем первом фрагменте кода перед var final ....Второй фрагмент тогда не будет использоваться, и поэтому ваша обработка ошибок там также должна быть перемещена ...

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