使用LINQ to SQL,我怎么贪婪加载所有的孩子和任何嵌套子结果(Using Linq to S

2019-07-30 22:11发布

我有一个L2S类5桌DBML:全球>>分类>> >>的ItemType项目>>的ItemData。 对于下面的例子中,我只就项目类型了。

    //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                            
        }
    }
}

“列表类型串= c.ItemTypes.ToList();”
这条线被在foreach执行了无数次,并执行一个查询获取的结果,我明白为什么在一定程度上,但我认为它会急于负荷Loadwith作为一个选项,如使用一个查询获取的一切。

所以基本上我本来期望在幕后L2S在一个查询中获取“全球性”的记录,采取任何主键值,使用1个查询得到的“类别”的孩子。 采取这些结果并坚持到连接全球的集合。 然后把所有的类别键和EXCUTE一个查询来获取项目类型的孩子和那些链接到他们的关联集合。 的(SELECT * FROM ItemTypes顺序凡在类别ID(从类别选择的categoryID在一些地方GlobalID在(#,#,#))

我想知道负载如何正确渴望有关以最小的查询和可能的孩子如何完成我的日常一般不知道我需要多远了建立层次结构,但由于父实体,抓住所有的相关的子集,然后做我需要做什么。

Answer 1:

LINQ到SQL相对于预先加载一定的局限性。

因此,在LINQ的贪婪加载到SQL只是在一次一级预先加载。 因为它是延迟加载,具有加载选项,我们还是会在根目录一级发行每行(或对象)一个查询,这是我们真正想要避免备用数据库。 这是一种用预先加载了点,以备用数据库。 LINQ to SQL的方式发出查询的层次结构将通过的log(n),其中n是根对象的数量降低性能。 调用ToList不会改变行为,但是当时间所有的查询将被发布到数据库,它就会控制。

有关详细信息,请参阅:

http://www.cnblogs.com/cw_volcano/archive/2012/07/31/2616729.html



Answer 2:

我相信这可以做得更好,但我得到了我的代码以最小的查询工作。 每一个级别。 这显然不是真正使用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
            .....
    // 

不会介意知道如何做到这一切使用泛型和递归方法给出的顶级表



文章来源: Using Linq to SQL, how do I Eager Load all child and any nested children results