【问题标题】:multiple Search parameters in Multiple joined tables using LINQ in DBML在 DBML 中使用 LINQ 的多个连接表中的多个搜索参数
【发布时间】:2019-03-14 10:42:58
【问题描述】:

我想为网站建立一个advanced multiple parameters search
这是我的 DBML 和 ORM 架构:
在这个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());
}

此功能完美运行,但现在我想添加更多来自 EstateEquipmentEstateFacility 的参数。
正如您在ORM 中看到的那样,EstateEstateEquipment(也包括EstateEstateFacility)之间的关系是one to many
现在我想用户可以在cityId = 1size around 400m 中搜索 Estate,例如 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 结果结合起来。
感谢您的帮助。

【问题讨论】:

    标签: c# asp.net linq linq-to-sql


    【解决方案1】:

    由于您的案例相当复杂,无法测试我的解决方案,我希望它至少能让您朝着正确的方向前进。

    我会说尝试这样的事情:

        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 ... 之前出现在您的第一个代码sn-p 中。第二个 sn-p 将不会被使用,因此您在那里的错误处理也需要移动......

    【讨论】:

    • 同意。以这种方式链接谓词时,始终最简单的方法是继续添加以查询根实体为根的谓词。
    • 感谢您的建议,但您会测试您的代码吗?不需要实现所有代码。只是一小部分,在这里与其他人分享。非常感谢
    猜你喜欢
    • 1970-01-01
    • 2016-03-04
    • 2015-11-04
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    相关资源
    最近更新 更多