我在L2S Classes中有5个表dbml:Global>>分类>> ItemType>>项目>>的ItemData。对于下面的示例,我只使用了itemtype。
//cdc is my datacontext
DataLoadOptions options = new DataLoadOptions();
options.LoadWith<Global>(p => p.Category);
options.AssociateWith<Global>(p => p.Category.OrderBy(o => o.SortOrder));
options.LoadWith<Category>(p => p.ItemTypes);
options.AssociateWith<Category>(p => p.ItemTypes.OrderBy(o => o.SortOrder));
cdc.LoadOptions = options;
TraceTextWriter traceWriter = new TraceTextWriter();
cdc.Log = traceWriter;
var query =
from g in cdc.Global
where g.active == true && g.globalid == 41
select g;
var globalList = query.ToList();
// In this case I have hardcoded an id while I figure this out
// but intend on trying to figure out a way to include something like globalid in (#,#,#)
foreach (var g in globalList)
{
// I only have one result set, but if I had multiple globals this would run however many times and execute multiple queries like it does farther down in the hierarchy
List<Category> categoryList = g.category.ToList<Category>();
// Doing some processing that sticks parent record into a hierarchical collection
var categories = (from comp in categoryList
where comp.Type == i
select comp).ToList<Category>();
foreach (var c in categories)
{
// Doing some processing that stick child records into a hierarchical collection
// Here is where multiple queries are run for each type collection in the category
// I want to somehow run this above the loop once where I can get all the Items for the categories
// And just do a filter
List<ItemType> typeList = c.ItemTypes.ToList<ItemType>();
var itemTypes = (from cat in TypeList
where cat.itemLevel == 2
select cat).ToList<ItemType>();
foreach (var t in itemTypes)
{
// Doing some processing that stick child records into a hierarchical collection
}
}
}
“List typeList = c.ItemTypes.ToList();”
这行在foreach中被执行多次,并且执行查询以获取结果,我理解为什么在某种程度上,但我认为它会急于加载Loadwith作为一个选项,就像用一个查询获取所有内容一样。
所以基本上我会期望L2S在幕后获取一个查询中的“全局”记录,获取任何主键值,使用一个查询获取“类别”子项。获取这些结果并将其粘贴到与全球相关的集合中。然后获取所有类别键并执行一个查询以获取itemtype子项并将其链接到其关联的集合中。按顺序排列的东西(从ItemTypes中选择*其中的CategoryID(从(#,#,#)中的GlobalID中选择categoryID中的categoryID)
我想知道如何通过最少的查询正确地加载关联的子项,以及可能如何完成我的例程,一般不知道构建层次结构需要多长时间,但是给定父实体,抓住所有关联的子集合然后做我需要做的事。
答案 0 :(得分:5)
Linq to SQL在急切加载方面有一些限制。
仅限Linq To SQL中的Eager Load 渴望一次加载一个级别。 因为它是延迟加载,使用Load 选项我们仍将发出一个查询 根级别的每行(或对象) 这是我们真正想要的 避免备用数据库。哪一个 渴望得到一点点 加载,以备用数据库。该 LINQ to SQL发出查询的方式 等级将减少 log(n)的性能,其中n是 根对象的数量。调用ToList 不会改变行为,但会改变 及时控制所有查询 将发给数据库。
详见:
http://www.cnblogs.com/cw_volcano/archive/2012/07/31/2616729.html
答案 1 :(得分:0)
我确信这可以做得更好,但我的代码使用最少的查询。每个级别一个。这显然不是真正渴望使用L2S加载,但如果有人知道正确的方式我想知道以供将来参考。
var query =
from g in cdc.Global
where g.active == true && g.globalId == 41
select g;
var globalList = query.ToList();
List<Category> categoryList = g.category.ToList<Category>();
var categoryIds = from c in cdc.Category
where c.globalId == g.globalId
select c.categoryId;
var types = from t in cdc.ItemTypes
where categoryIds.Any(i => i == t.categoryId)
select t;
List<ItemType> TypeList = types.ToList<ItemType>();
var items = from i in cdc.Items
from d in cdc.ItemData
where i.ItemId == d.ItemId && d.labelId == 1
where types.Any(i => i == r.ItemTypes)
select new
{
i.Id,
// A Bunch of more fields shortened for berevity
d.Data
};
var ItemList = items.ToList();
// Keep on going down the hierarchy if you need more child results
// Do your processing psuedocode
for each item in list
filter child list
for each item in child list
.....
//
不介意知道如何使用泛型和给定顶级表的递归方法来完成所有这些