使用LINQ子查询填充子集合属性
一般来说,我对LINQ还比较陌生,但到目前为止,我已经设法解决了一些问题,以获得我想要/需要的结果。下面的LINQ2SQL查询生成所需的结果,其中有位置对象,每个对象都有自己的单元集合。最初的变量声明是为了设置我需要查询的值,这些值不应该与我的问题相关,而是上下文所需要的 我遇到的问题是,有400多个位置,按照我目前的查询结构,它会针对每个位置而不是一个大查询命中数据库。这导致性能大大降低,需要30多秒才能恢复完整结果,这是不可接受的。我有一个存储过程SQL查询,它仅在一两秒钟内返回结果 有没有一种方法可以重新构造这个查询,这样我就不会访问每个位置的数据库?我确信这是由Units子查询上的额外“ToList()”引起的,但我不知道如果没有ToList(),如何形成结果。任何性能调整都将是巨大的帮助。谢谢你的帮助使用LINQ子查询填充子集合属性,linq,linq-to-sql,Linq,Linq To Sql,一般来说,我对LINQ还比较陌生,但到目前为止,我已经设法解决了一些问题,以获得我想要/需要的结果。下面的LINQ2SQL查询生成所需的结果,其中有位置对象,每个对象都有自己的单元集合。最初的变量声明是为了设置我需要查询的值,这些值不应该与我的问题相关,而是上下文所需要的 我遇到的问题是,有400多个位置,按照我目前的查询结构,它会针对每个位置而不是一个大查询命中数据库。这导致性能大大降低,需要30多秒才能恢复完整结果,这是不可接受的。我有一个存储过程SQL查询,它仅在一两秒钟内返回结果 有没有
Dim curNames1 = (From ons In dc.organization_names _
Where ons.eff_date <= ssDate _
Order By ons.eff_date Descending _
Group ons By ons.organization_id Into gNames = Group _
Select New With { _
Key .Key = organization_id, _
.Result = gNames.Take(1)}) _
.SelectMany(Function(a) (a.Result))
Dim curLocs1 = (From oLocs In dc.organization_locations _
Where oLocs.eff_date <= ssDate _
Order By oLocs.eff_date Descending _
Group oLocs By oLocs.organization_id Into gLocs = Group _
Select New With { _
Key .Key = organization_id, _
Result = gLocs.Take(1)}) _
.SelectMany(Function(a) (a.Result))
Dim curStatuses1 = (From oEDate In dc.organization_conversion_dates _
Where oEDate.edate <= ssDate _
Order By oEDate.edate Descending _
Group oEDate By oEDate.organization_id Into gEDates = Group _
Select New With { _
Key .Key = organization_id, _
.Result = gEDates.Take(1)}) _
.SelectMany(Function(a) (a.Result))
Dim curCommand1 = (From oCommand In dc.organization_service_assigneds _
Where oCommand.eff_date <= ssDate _
Order By oCommand.eff_date Descending _
Group oCommand By oCommand.organization_id Into gCmds = Group _
Select New With { _
Key .Key = organization_id, _
.Result = gCmds.Take(1)}) _
.SelectMany(Function(a) (a.Result))
Dim curComponent1 = (From oCompo In dc.organization_compos _
Where oCompo.eff_date <= ssDate _
Order By oCompo.eff_date Descending _
Group oCompo By oCompo.organization_id Into gCompos = Group _
Select New With { _
Key .Key = organization_id, _
.Result = gCompos.Take(1)}) _
.SelectMany(Function(a) (a.Result))
ss.Locations = New ObservableCollection(Of Location)(( _
From map In dc.MapBackgrounds Where map.MapID = options.Map _
Let Locs = map.Schemes.SchemeLocations _
From SchemeLoc In Locs _
Where (options.Locations.Count = 0 Or _
options.Locations.Contains(SchemeLoc.Location.ID)) _
Select New Location With { _
.ID = SchemeLoc.Location.ID, .Name = SchemeLoc.Location.Location, _
.Y = SchemeLoc.Y, .X = SchemeLoc.X, _
.Country = New Country With _
{.ID = SchemeLoc.Location.Countries.ID, _
.Name = SchemeLoc.Location.Countries.country}, _
.State = If(SchemeLoc.Location.State = -1, Nothing, _
New USState With {.ID = SchemeLoc.Location.States.ID, _
.Name = SchemeLoc.Location.States.state, _
.Abbreviation = SchemeLoc.Location.States.state}), _
.Units = New ObservableCollection(Of MillitaryUnit)(( _
From curLoc In curLocs1 _
Where curLoc.location = SchemeLoc.Location.ID _
From curName In curNames1 _
Where curName.organization_id = curLoc.organization_id _
And (options.UnitSizes.Count = 0 Or _
options.UnitSizes.Contains(curName.UnitSize)) _
And (options.UnitTypes.Count = 0 Or _
options.UnitTypes.Contains(curName.UnitType)) _
From curEDate In curStatuses1 _
Where curEDate.organization_id = curLoc.organization_id _
And (options.Statuses.Count = 0 Or _
options.Statuses.Contains(curEDate.status)) _
From curCmd In curCommand1 _
Where curCmd.organization_id = curLoc.organization_id _
And (options.Commands.Count = 0 Or _
options.Commands.Contains(curCmd.service_assigned)) _
From curCompo In curComponent1 _
Where curCompo.organization_id = curLoc.organization_id _
And (options.Components.Count = 0 Or _
options.Components.Contains(curCompo.compo)) _
From curTable In curLoc.Organization.organization_tables _
Where curTable.organization_id = curLoc.organization_id _
And (options.Tables.Count = 0 Or _
(options.Tables.Contains(curTable.table_id) Or _
curTable.Tables.Any(Function(a) (options.Tables.Contains(a.parent_id))))) _
Select New MillitaryUnit With { _
.ID = curLoc.organization_id, _
.Name = curName.name, _
.IconPath = curName.icon, _
.ConversionStatus = curEDate.Status1.status, _
.ServiceCommand = curCmd.Service_Assigneds.service_assigned, _
.Component = curCompo.Components.compo}).Distinct().ToList())}).ToList())
将属性类型更改为
IEnumerable
或IQueryable
,而不是将成员公开为列表。然后,您可以删除对ToList的调用,并且您的查询应该能够在服务器上一次性完全执行
此外,我认为,这种代码正是LINQ到SQL开始崩溃的地方。我认为,如果您有一个存储过程可以提供所需的结果,那么您应该使用它,让LINQ到SQL处理返回数据到对象的映射。而不是将成员作为列表公开,将属性类型更改为IEnumerable
或IQueryable
。然后,您可以删除对ToList的调用,并且您的查询应该能够在服务器上一次性完全执行
此外,我认为,这种代码是LINQ to SQL开始崩溃的地方。我认为,如果您有一个存储过程可以提供所需的结果,那么您应该使用它,只需让LINQ to SQL处理返回数据到对象的映射。因此,我最终重做了一些事情,并提出了以下解决方案,该解决方案只需查询数据库两次,而且速度更快:
Dim locationsOnly = (From map In dc.MapBackgrounds Where map.MapID = 1 Let Locs = map.Schemes.SchemeLocations _
From SchemeLoc In Locs _
Where (options.Locations.Count = 0 Or options.Locations.Contains(SchemeLoc.LocID)) _
Select New With {.LocationID = SchemeLoc.LocID, .X = SchemeLoc.X, .Y = SchemeLoc.Y, _
.LocationName = SchemeLoc.Location.Location, _
.CountryID = SchemeLoc.Location.Countries.ID, .CountryName = SchemeLoc.Location.Countries.country, _
.StateID = SchemeLoc.Location.State, .StateName = SchemeLoc.Location.States.state, .StateAbbrev = SchemeLoc.Location.States.state}).ToList()
Dim orgsOnly = (From curLoc In curLocs1 _
Join curName In curNames1 On curLoc.organization_id Equals curName.organization_id _
Join curStatus In curStatuses1 On curLoc.organization_id Equals curStatus.organization_id _
Join curCommand In curCommand1 On curLoc.organization_id Equals curCommand.organization_id _
Join curComponent In curComponent1 On curLoc.organization_id Equals curComponent.organization_id _
Join curTable In dc.organization_tables On curLoc.organization_id Equals curTable.organization_id _
Where (options.UnitSizes.Count = 0 Or options.UnitSizes.Contains(curName.UnitSize)) _
And (options.UnitTypes.Count = 0 Or options.UnitTypes.Contains(curName.UnitType)) _
And (options.Statuses.Count = 0 Or options.Statuses.Contains(curStatus.status)) _
And (options.Commands.Count = 0 Or options.Commands.Contains(curCommand.service_assigned)) _
And (options.Components.Count = 0 Or options.Components.Contains(curComponent.compo)) _
And (options.Tables.Count = 0 Or (options.Tables.Contains(curTable.table_id) Or curTable.Tables.Any(Function(a) (options.Tables.Contains(a.parent_id))))) _
Select New With {.OrgLocID = curLoc.location, _
.MilUnit = New MillitaryUnit With { _
.ID = curLoc.organization_id, _
.Name = curName.name, _
.IconPath = curName.icon, _
.ConversionStatus = curStatus.Status1.status, _
.ServiceCommand = curCommand.Service_Assigneds.service_assigned, _
.Component = curComponent.Components.compo}}).Distinct().ToList()
ss.Locations = New System.Collections.ObjectModel.ObservableCollection(Of Location)((From loc In locationsOnly _
Group Join org In orgsOnly On loc.LocationID Equals org.OrgLocID Into Orgs = Group _
Select New Location With { _
.ID = loc.LocationID, _
.Name = loc.LocationName, _
.X = loc.X, _
.Y = loc.Y, _
.Country = New Country With {.ID = loc.CountryID, .Name = loc.CountryName}, _
.State = New USState With {.ID = loc.StateID, .Name = loc.StateName, .Abbreviation = loc.StateAbbrev}, _
.Units = New System.Collections.ObjectModel.ObservableCollection(Of MillitaryUnit)((From curOrg In Orgs _
Select curOrg.MilUnit).ToList())}).ToList())
谢谢你的帮助casperOne 因此,我最终重做了一些事情,并提出了以下解决方案,该解决方案只需查询数据库两次,而且速度要快得多:
Dim locationsOnly = (From map In dc.MapBackgrounds Where map.MapID = 1 Let Locs = map.Schemes.SchemeLocations _
From SchemeLoc In Locs _
Where (options.Locations.Count = 0 Or options.Locations.Contains(SchemeLoc.LocID)) _
Select New With {.LocationID = SchemeLoc.LocID, .X = SchemeLoc.X, .Y = SchemeLoc.Y, _
.LocationName = SchemeLoc.Location.Location, _
.CountryID = SchemeLoc.Location.Countries.ID, .CountryName = SchemeLoc.Location.Countries.country, _
.StateID = SchemeLoc.Location.State, .StateName = SchemeLoc.Location.States.state, .StateAbbrev = SchemeLoc.Location.States.state}).ToList()
Dim orgsOnly = (From curLoc In curLocs1 _
Join curName In curNames1 On curLoc.organization_id Equals curName.organization_id _
Join curStatus In curStatuses1 On curLoc.organization_id Equals curStatus.organization_id _
Join curCommand In curCommand1 On curLoc.organization_id Equals curCommand.organization_id _
Join curComponent In curComponent1 On curLoc.organization_id Equals curComponent.organization_id _
Join curTable In dc.organization_tables On curLoc.organization_id Equals curTable.organization_id _
Where (options.UnitSizes.Count = 0 Or options.UnitSizes.Contains(curName.UnitSize)) _
And (options.UnitTypes.Count = 0 Or options.UnitTypes.Contains(curName.UnitType)) _
And (options.Statuses.Count = 0 Or options.Statuses.Contains(curStatus.status)) _
And (options.Commands.Count = 0 Or options.Commands.Contains(curCommand.service_assigned)) _
And (options.Components.Count = 0 Or options.Components.Contains(curComponent.compo)) _
And (options.Tables.Count = 0 Or (options.Tables.Contains(curTable.table_id) Or curTable.Tables.Any(Function(a) (options.Tables.Contains(a.parent_id))))) _
Select New With {.OrgLocID = curLoc.location, _
.MilUnit = New MillitaryUnit With { _
.ID = curLoc.organization_id, _
.Name = curName.name, _
.IconPath = curName.icon, _
.ConversionStatus = curStatus.Status1.status, _
.ServiceCommand = curCommand.Service_Assigneds.service_assigned, _
.Component = curComponent.Components.compo}}).Distinct().ToList()
ss.Locations = New System.Collections.ObjectModel.ObservableCollection(Of Location)((From loc In locationsOnly _
Group Join org In orgsOnly On loc.LocationID Equals org.OrgLocID Into Orgs = Group _
Select New Location With { _
.ID = loc.LocationID, _
.Name = loc.LocationName, _
.X = loc.X, _
.Y = loc.Y, _
.Country = New Country With {.ID = loc.CountryID, .Name = loc.CountryName}, _
.State = New USState With {.ID = loc.StateID, .Name = loc.StateName, .Abbreviation = loc.StateAbbrev}, _
.Units = New System.Collections.ObjectModel.ObservableCollection(Of MillitaryUnit)((From curOrg In Orgs _
Select curOrg.MilUnit).ToList())}).ToList())
谢谢你的帮助casperOne 我设法在一次查询中把它全部找回来。你们能看一下我编辑的帖子,看看我在哪里遇到了一个问题吗?谢谢我设法在一次查询中把它全部找回来。你们能看一下我编辑的帖子,看看我在哪里遇到了一个问题吗?谢谢