我可以使用一些帮助来确定从SQL数据库中检索父子对象的最佳(最高性能/易维护)策略。父子表的SQL策略
我继承了这段代码,而且我已经有了相对较短的截止日期,我希望尽可能少做基础性更改。我有足够的时间在下一个螺旋上实现nhibernate或其他ORM,我现在不能这样做。我以最少的修改时间在最短的时间内寻找最好的事情。
扭曲的是,有不同的儿童类型(实现一个普通的儿童界面)。
例如,
家长:VehicleFleet(包含车队名称,经理姓名,车辆列表)
儿童:IVehicle(包括制造商,型号,位置等)
但是,可能有多个车辆类型 - 例如汽车,厢式车,摩托车 - 各具有不同的属性/列。有一个独立的汽车,面包车和摩托车。可能有也可能没有VehicleBase表,其中包含适用于任何车辆的列。
返回多个VehicleFleet对象的最佳策略是什么,每个对象都有相关的Vehicle子对象?
这里有一对夫妇的战略我已经试过(伪代码提交) -
假设:
所有的getXXXX功能使用DataReader场景
方法1落后:简单&慢 - 这是做的最糟糕的方式,原因很明显
IEnumerable<Fleet> GetFleetsAndVehicles() {
foreach (var fleet in myFleetDao.GetAllFleets()) {
foreach (var vehicleTypeDao in myVehicleTypeDaos)
fleet.Vehicles.Add (vehicleTypeDao.GetVehicles (fleet.Id);
yield return fleet;
}
yield break;
}
方法2:预取儿童
IEnumerable<Fleet> GetFleetsAndVehicles() {
var allVehicles = (from vtd in myVehicleTypeDaos
from v in vtd.GetAllVehicles()
select v).ToLookup (v => v.FleetId);
foreach (var fleet in myFleetDao.GetAllFleets())
{
fleet.Vehicles = allVehicles[fleet.Id].ToList();
yield return fleet;
}
yield break;
}
方法3:预取儿童,儿童附加异步地
IEnumerable<Fleet> GetFleetsAndVehicles() {
foreach (var fleet in new AsyncGetter.GetFleetsAndVehicles())
yield return fleet;
yield break;
}
class AsyncGetter
{
// left out instance variables, Auto/Manual Reset Events, locking, etc. for brevity
IEnumerable<Fleet> GetFleetsAndVehicles()
{
StartAsyncStuff();
while (myUnconsumedFleets.Count > 0)
{
yield return myUnconsumedFleets.Remove (0);
WaitUntilMoreFleetsAreAdded();
}
yield break;
}
void StartAsyncStuff()
{
myAllVehicles = <same as method 2>
foreach (var fleet in myFleetDao.GetAllFleets())
{
AttachVehiclesAsync (fleet);
}
}
void AttachVehiclesAsync (Fleet f)
{
// assume using ThreadPool.QueueUserWorkItem right now
WaitForAllVehiclesToLoad();
f.Vehicles = myAllVehicles[f.Id].ToList();
myUnconsumedFleets.Add (f);
}
}
方法4:交错的父/子查询
IEnumerable<Fleet> GetFleetsAndVehicles() {
var allVehicles = from vtd in myVehicleTypeDaos
from v in vtd.GetAllVehicles()
orderby v.FleetId
select v;
var allVehiclesEnumerator = allVehicles.GetEnumerator();
foreach (var fleet in myFleetDao.GetAllFleets())
{
fleet.Vehicles = GetAllChildVehiclesAndMaintainEnumeratorPosition (allVehiclesEnumerator, fleet);
yield return fleet;
}
}
到目前为止,使用一些测试数据,我看到那个方法3是最高性能的(快于下一个最佳速度27%),而方法1是最差的(比方法1慢4倍)。
所以,如果你有建议,我很乐意听到他们!
如果您可以自由选择单个表继承模型,而不是在LINQ2SQL中内置支持,请参阅http://msdn.microsoft.com/en-us/library/bb399352.aspx和http:// msdn。 microsoft.com/en-us/library/bb386919.aspx – 2010-08-28 07:14:01