C# 优化LINQ查询,检查结果是否有值
我让LINQ query检查查询结果并结束语句。该数据库有大约600k的数据。下面是LINQ查询和if语句C# 优化LINQ查询,检查结果是否有值,c#,database,linq,C#,Database,Linq,我让LINQ query检查查询结果并结束语句。该数据库有大约600k的数据。下面是LINQ查询和if语句 var feetypelist = from feetype in dbDataContext.tbl_fee_types orderby feetype.seq select feetype.id; foreach (var fty in feetypelist)
var feetypelist = from feetype in dbDataContext.tbl_fee_types
orderby feetype.seq
select feetype.id;
foreach (var fty in feetypelist)
{
var checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.arr == arr && fee.dep == dep && fee.feetypeid == fty && fee.site_id == siteId
orderby fee.seq
select fee;
if (checkFeeCharges.Count() == 0)
{
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.arr == arr && fee.dep == dep && fee.feetypeid == fty && fee.site_id == siteId
&& fee.country == country
orderby fee.seq
select fee;
}
if (checkFeeCharges.Count() == 0)
{
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.site_id == siteId && fee.country == country &&
((fee.arr == arr && fee.dep == dep) || (fee.arr.Equals("DOM") && fee.dep.Equals("DOM")) ||
(fee.arr.Equals("*") && fee.dep == dep) || (fee.arr == arr && fee.dep.Equals("*")))
&& fee.feetypeid == fty
orderby fee.seq
select fee;
if (checkFeeCharges.Count() == 0)
{
var country_route = from route in dbDataContext.tbl_country_routes
where route.origin_airport_cd == arr && route.destination_airport_cd == dep
select route;
if (country_route.Count() >= 1)
{
foreach (var c in country_route)
{
if (c.air_asiax == 'Y')
{
//con_flight = "Y";
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.site_id == siteId && fee.country == country &&
((fee.arr == "AAX" && fee.dep == "AAX") || (fee.arr == "*" && fee.dep == dep) ||
(fee.arr == arr && fee.dep == "*")) && fee.feetypeid == fty
orderby fee.seq
select fee;
if (checkFeeCharges.Count() == 0)
{
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.site_id == siteId && fee.country == country &&
((fee.arr == arr && fee.dep == dep) || (fee.arr == "INT" && fee.dep == "INT") ||
(fee.arr == "*" && fee.dep == dep) || (fee.arr == arr && fee.dep == "*") ||
(fee.arr == country && fee.dep == country)) &&
fee.feetypeid == fty
orderby fee.seq
select fee;
}
}
else
{
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.site_id == siteId && fee.country == country &&
((fee.arr == arr && fee.dep == dep) || (fee.arr == "INT" && fee.dep == "INT") ||
(fee.arr == "*" && fee.dep == dep) || (fee.arr == arr && fee.dep == "*") ||
(fee.arr == country && fee.dep == country)) &&
fee.feetypeid == fty
orderby fee.seq
select fee;
}
}
}
else
{
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.site_id == siteId && fee.country == country &&
((fee.arr == arr && fee.dep == dep) || (fee.arr == "INT" && fee.dep == "INT") ||
(fee.arr == "*" && fee.dep == dep) || (fee.arr == arr && fee.dep == "*")) &&
fee.feetypeid == fty
orderby fee.seq
select fee;
}
}
}
if (checkFeeCharges.Count() == 0)
{
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.site_id == siteId && fee.country == country &&
((fee.arr == arr && fee.dep == dep) || (fee.arr == "INT" && fee.dep == "INT") ||
(fee.arr == "*" && fee.dep == dep) || (fee.arr == arr && fee.dep == "*")) &&
fee.feetypeid == fty
orderby fee.seq
select fee;
}
查询执行需要一段时间才能完成,您知道如何优化此查询吗
返回json请求
if (checkFeeCharges.Any())
{
List<FeeAndChargesModel_Fee_Schedule> feeTable = new List<FeeAndChargesModel_Fee_Schedule>();
foreach (var p in checkFeeCharges)
{
feeTable.Add(
new FeeAndChargesModel_Fee_Schedule()
{
arr = FlightScheduleAPIController.GetCountryName(arr, siteId),
dep = FlightScheduleAPIController.GetCountryName(dep, siteId),
country = p.country,
feedesc = p.feedesc,
feetype = p.feetype,
currency = p.currency,
value = p.value,
remark = p.remark
}
);
label = p.feetype;
}
mainJson.Add(
new FeeAndChargesModel_Main
{
label = label,
con_flight = FlightScheduleAPIController.GetCountryName(GetConnectingFlight(dep, arr), siteId),
details = feeTable
}
);
}
}
return mainJson;
if(checkFeeCharges.Any())
{
List feeTable=新列表();
foreach(支票费用中的var p)
{
feeTable.添加(
新的费用和收费模式费用表()
{
arr=FlightScheduleAPIController.GetCountryName(arr,站点ID),
dep=FlightScheduleAPIController.GetCountryName(dep,站点ID),
country=p.country,
feedesc=p.feedesc,
feetype=p.feetype,
货币=p.货币,
值=p.value,
备注
}
);
标签=p.feetype;
}
mainJson.Add(
新的费用和收费模式
{
标签=标签,
con_flight=FlightScheduleAPIController.GetCountryName(GetConnectingFlight(dep,arr),siteId),
详细信息=可测
}
);
}
}
返回mainJson;
很难说如何优化它,因为这里有很多重复。我会先尝试减少这个
一个明显的变化是:
if (checkFeeCharges.Count() == 0)
这将在每次调用时枚举整个查询。一种更便宜的检查相同内容的方法:
if (!checkFeeCharges.Any())
这将只从查询中枚举一个结果,以确定它是否为空。好的,因此这段代码确实很难阅读,但让我们给您一些建议 我注意到的第一件事是执行了第一条sql语句
var checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.arr == arr && fee.dep == dep && fee.feetypeid == fty && fee.site_id == siteId
orderby fee.seq
select fee;
如果它什么也不返回呢
if (checkFeeCharges.Count() == 0)
{
它执行一个比第一个更具体的sql查询。它具有所有相同的AND语句+另一个语句。如果第一个查询没有返回任何内容,那么第二个查询应该没有返回任何内容。如果是的话,为什么要这样做
checkFeeCharges = from fee in dbDataContext.tbl_fee_schedules
where fee.arr == arr && fee.dep == dep && fee.feetypeid == fty && fee.site_id == siteId
&& fee.country == country
orderby fee.seq
select fee;
}
就我个人而言,我会尝试理解或解决以下问题
1预期的结果集大小是多少,我是否可以检索“少量”记录并在内存中处理这些记录。我需要了解结果集是否会随着时间的推移而增长,以及它的最小、最大类型边界
2是否有更好的数据库结构,我可以重构代码以使用它,从而使查询更简单、更高效
3
为了真正能够优化这个查询,我将尝试首先直接在sql中编写它,并使用explain来帮助准确理解sql数据库在做什么,使用了哪些索引,以及每个查询返回的结果集的大小
。我还相信,您应该能够将大量查询组合到一个表达式中
这可能并不完全正确,但作为一个演示应该可以
from fee in dbDataContext.tbl_fee_schedules
where (fee.arr == arr && fee.dep == dep && fee.feetypeid == fty && fee.site_id == siteId
&& fee.country == country) || (fee.site_id == siteId && fee.country == country &&
((fee.arr == "AAX" && fee.dep == "AAX") || (fee.arr == "*" && fee.dep == dep) ||
(fee.arr == arr && fee.dep == "*")) && fee.feetypeid == fty)
|| ( ..... ) | ( .... )
从这里我可以看到,您将需要几个连接或子选择,这就是为什么在sql中尝试它将是最快的。此外,还有许多linq2sql/ORM分析工具,它们可能有助于诊断。同样的事情。当我们谈论优化性能时,我们不能考虑这一点。@ Roshana:事实上,马歇恩有不同之处。我希望他使用的数据库(他提到的)会更正确。这真的取决于sql在幕后发生了什么。谢谢@Alistair的建议。。我已经落实了你的一些建议。。问题是“foreach(feetypelist中的var fty)”将循环37次。。因为我们有37种收费类型。。我们在LINQ上有针对这个问题的优化代码吗?想把完整的代码块贴在哪里吗?看起来您的代码实际上什么都不做,可以用nop替换。在所有这些查询之后,
checkFeeCharges
会发生什么?你最终还了吗?列举一下?根据您正在执行的操作,您可能会提前返回。添加其余代码。。它将使用(非).Any()而不是.count()返回json结果==0@Lavinskidone implement.Any()的结果仍然相同。。