我有一个需要优化的Linq查询。
修改
我想我想要做的就是选择第一个表中的所有行,但选择Survey,CB和Science表中的最后一行或默认行......
修改
当这创建一个查询时,我针对整个查询点击了一次数据库,然后再次针对每个结果我从第一个查询返回。因此,如果TestClass返回30个结果,那么我会为调查对象多次点击DB 30。
我真的需要一种更好的方法来完成这项工作。
提前致谢!
示例查询
return (from xx in db.test
select new TestClass {
Added_By_User_ID = xx.Added_By_User_ID,
Survey = (from ru in db.Utopia
where ru.Province_ID == xx.Province_ID
orderby ru.uid descending
select ru).Take(1).ToList(),
}).ToList();
真实查询
return (from xx in db.Utopia_Province_Data_Captured_Gens
where xx.Owner_Kingdom_ID == ownerKingdomID
where kingdomList.Contains((Guid)xx.Kingdom_ID)
select new ProvinceClass
{
Kingdom_ID = xx.Kingdom_ID,
Kingdom_Island = xx.Kingdom_Island,
Kingdom_Location = xx.Kingdom_Location,
Owner_Kingdom_ID = xx.Owner_Kingdom_ID,
Province_ID = xx.Province_ID,
Province_Name = xx.Province_Name,
Owner_User_ID = xx.Owner_User_ID,
Race_ID = xx.Race_ID,
Updated_By_DateTime = xx.Updated_By_DateTime,
Networth = xx.Networth,
Land = xx.Land,
Monarch_Display = xx.Monarch_Display,
Owner = xx.Owner,
Sub_Monarch = xx.Sub_Monarch,
CB_Updated_By_Province_ID = xx.CB_Updated_By_Province_ID,
uid = xx.uid,
Formatted_By = xx.Formatted_By,
Utopian_Day_Month = xx.Utopian_Day_Month,
Utopian_Year = xx.Utopian_Year,
Ruler_Name = xx.Ruler_Name,
Personality_ID = xx.Personality_ID,
Nobility_ID = xx.Nobility_ID,
Money = xx.Money,
Daily_Income = xx.Daily_Income,
Food = xx.Food,
Runes = xx.Runes,
Population = xx.Population,
Peasents = xx.Peasents,
Peasents_Non_Percentage = xx.Peasents_Non_Percentage,
Trade_Balance = xx.Trade_Balance,
Building_Effectiveness = xx.Building_Effectiveness,
Military_Efficiency_Off = xx.Military_Efficiency_Off,
Military_Efficiency_Def = xx.Military_Efficiency_Def,
Draft = xx.Draft,
Soldiers = xx.Soldiers,
Soldiers_Regs_Off = xx.Soldiers_Regs_Off,
Soldiers_Regs_Def = xx.Soldiers_Regs_Def,
Soldiers_Elites = xx.Soldiers_Elites,
War_Horses = xx.War_Horses,
//Prisoners = xx.Prisoners,
Military_Net_Off = xx.Military_Net_Off,
Military_Net_Def = xx.Military_Net_Def,
Military_Current_Off = xx.Military_Current_Off,
Military_Current_Def = xx.Military_Current_Def,
Mil_Training = xx.Mil_Training,
Mil_Wage = xx.Mil_Wage,
Mil_Overall_Efficiency = xx.Mil_Overall_Efficiency,
Mil_Total_Generals = xx.Mil_Total_Generals,
Wizards = xx.Wizards,
Wizards_Value_Type = xx.Wizards_Value_Type,
Thieves = xx.Thieves,
Thieves_Value_Type = xx.Thieves_Value_Type,
Plague = xx.Plague,
Monarch_Vote_Province_ID = xx.Monarch_Vote_Province_ID,
Protected = xx.Protected,
Hit = xx.Hit,
Honor = xx.Honor,
Province_Notes = xx.Province_Notes,
CB_Export_Line = xx.CB_Export_Line,
Army_Out = xx.Army_Out,
Army_Out_Expires = xx.Army_Out_Expires,
Updated_By_Province_ID = xx.Updated_By_Province_ID,
SOM_Updated_By_Province_ID = xx.SOM_Updated_By_Province_ID,
SOM_Updated_By_DateTime = xx.SOM_Updated_By_DateTime,
CB_Updated_By_DateTime = xx.CB_Updated_By_DateTime,
CB_Requested = xx.CB_Requested,
CB_Requested_Province_ID = xx.CB_Requested_Province_ID,
SOM_Requested = xx.SOM_Requested,
SOM_Requested_Province_ID = xx.SOM_Requested_Province_ID,
SOS_Requested = xx.SOS_Requested,
SOS_Requested_Province_ID = xx.SOS_Requested_Province_ID,
Survey_Requested = xx.Survey_Requested,
Survey_Requested_Province_ID = xx.Survey_Requested_Province_ID,
Last_Login_For_Province = xx.Last_Login_For_Province,
Date_Time_User_ID_Linked = xx.Date_Time_User_ID_Linked,
Added_By_User_ID = xx.Added_By_User_ID,
NoteCount = (from yy in db.Utopia_Province_Notes
where yy.Province_ID == xx.Province_ID
select yy).Count(),
SOM = (from uu in db.Utopia_Province_Data_Captured_Type_Militaries
where uu.Province_ID == xx.Province_ID
where uu.Owner_Kingdom_ID == ownerKingdomID
where uu.DateTime_Added == (from ru in db.Utopia_Province_Data_Captured_Type_Militaries //datetime can be same for multiple items.
where ru.Province_ID == xx.Province_ID
where ru.Owner_Kingdom_ID == ownerKingdomID
orderby ru.uid descending // To get the last most inserted rows
select ru.DateTime_Added).FirstOrDefault()
select uu).ToList(),
SOS = (from zz in db.Utopia_Province_Data_Captured_Sciences
where ru.Province_ID == xx.Province_ID
where ru.Owner_Kingdom_ID == ownerKingdomID
orderby ru.uid descending
select ru).Take(1).ToList(),
Survey = (from ru in db.Utopia_Province_Data_Captured_Surveys
where ru.Province_ID == xx.Province_ID
where ru.Owner_Kingdom_ID == ownerKingdomID
orderby ru.uid descending
select ru).Take(1).ToList(),
CB = (from ru in db.Utopia_Province_Data_Captured_CBs
where ru.Province_ID == xx.Province_ID
where ru.Owner_Kingdom_ID == ownerKingdomID
orderby ru.uid descending
select ru).Take(1).ToList()
}).ToList();
答案 0 :(得分:2)
您可以从您的Utopia表中进行选择,然后加入第二个表来获取user_id,如:
from ru in db.Utopia
join xx in test on ru.Province_ID equals xx.Province_ID
orderby ru.uid descending
select new TestClass
{
Added_By_User_ID = xx.Added_By_User_ID,
Survey = ru
}
真实查询的更新
这是一个大规模的查询,你应该考虑一种基于连接的方法,正如我所建议的那样,并基于Jim McKeeth建议的本地缓存。或者你应该一起创建一个新表。
当您需要从多个表中查询可选数据时,您可以执行左连接:
from ru in db.Utopia
join user in db.Users on ru.UserId equals user.Id // User is required
join survey in db.Surveys on ru.Province_ID equals survey.Province_ID into j1
from survey in j1.DefaultIfEmpty() // Survey is optional (left join)
join address in db.Address on ru.UserId equals address.UserId into j2
from survey in j2.DefaultIfEmpty() // Address is optional (left join)
orderby ru.uid descending
select new TestClass
{
Added_By_User_ID = xx.Added_By_User_ID,
Survey = survey,
Street = address.Street,
UserName = new UserName
{
FirstName = user.FirstName,
LastName = user.LastName
}
}
请注意,连接数量会影响查询的性能。迟早,通过缓存找到更好的方法会变得更有效率。
另一个注意事项是,在查询中调用ToList()将实际执行查询的那部分(或整个查询)。
答案 1 :(得分:0)
类似的东西:
from xx in db.test
join ru in db.Utopia on xx.Province_ID equals ru.Province_ID
orderby ru.uid descending
select new ..
答案 2 :(得分:0)
您对我的真实查询的复杂性表明您应该将此LINQ语句移动到存储过程中,然后再调用它。
我建议这样做是因为(a)您可以完全控制查询的执行方式,(b)在TSQL中分析和性能优化查询要容易得多。这是我们过去在大型项目中使用的策略,当结果集生成变得非常重要时。
我还建议您使用AutoMapper执行将sproc结果传输到DTO的任务,因为您似乎有一个接近1:1的映射