26

我有以下 linq-to-entities 查询,其中包含 2 个要添加分页的连接表:

IQueryable<ProductInventory> data = from inventory in objContext.ProductInventory
    join variant in objContext.Variants
        on inventory.VariantId equals variant.id
     where inventory.ProductId == productId
     where inventory.StoreId == storeId
     orderby variant.SortOrder
     select inventory;

我意识到我需要使用 .Join() 扩展方法,然后调用 .OrderBy().Skip().Take() 来执行此操作,我只是被 Join() 的语法绊倒了,似乎无法查找任何示例(在线或书籍中)。

注意:我加入表格的原因是进行排序。如果有比连接更好的基于相关表中的值进行排序的方法,请将其包含在您的答案中。

2 可能的解决方案

我想这只是一个可读性问题,但这两者都可以工作并且在语义上是相同的。

1

IQueryable<ProductInventory> data = objContext.ProductInventory
                .Where(y => y.ProductId == productId)
                .Where(y => y.StoreId == storeId)
                .Join(objContext.Variants,
                    pi => pi.VariantId,
                    v => v.id,
                    (pi, v) => new { Inventory = pi, Variant = v })
                .OrderBy(y => y.Variant.SortOrder)
                .Skip(skip)
                .Take(take)
                .Select(x => x.Inventory);

2

var query = from inventory in objContext.ProductInventory
    where inventory.ProductId == productId
    where inventory.StoreId == storeId
    join variant in objContext.Variants
        on inventory.VariantId equals variant.id
    orderby variant.SortOrder
    select inventory;

var paged = query.Skip(skip).Take(take);

感谢 Khumesh 和 Pravin 在这方面提供的帮助。感谢其他人的贡献。

4

4 回答 4

8

在映射中定义连接,然后使用它。通过使用该方法,您真的不会得到任何东西Join- 相反,使用该Include方法。它好多了。

var data = objContext.ProductInventory.Include("Variant")
               .Where(i => i.ProductId == productId && i.StoreId == storeId)
               .OrderBy(j => j.Variant.SortOrder)
               .Skip(x)
               .Take(y);
于 2012-04-19T06:20:40.990 回答
5

将以下行添加到您的查询中

var pagedQuery = data.Skip(PageIndex * PageSize).Take(PageSize); 

数据变量是 IQueryable,所以你可以在它上面加上 add skip & take 方法。如果您在 Product 和 Variant 之间有关系,您实际上并不需要明确加入,您可以像这样引用变体

IQueryable<ProductInventory> data = 
             from inventory in objContext.ProductInventory
             where inventory.ProductId == productId && inventory.StoreId == storeId
             orderby inventory.variant.SortOrder
             select new()
             {
                 property1 = inventory.Variant.VariantId,
                 //rest of the properties go here
             }
pagedQuery = data.Skip(PageIndex * PageSize).Take(PageSize); 
于 2012-04-19T06:02:32.780 回答
1

我的答案基于标记为 true 的答案,但在这里我添加了上面代码的新最佳实践

    var data= (from c in db.Categorie.AsQueryable().Join(db.CategoryMap,
                    cat=> cat.CategoryId, catmap => catmap.ChildCategoryId, 
    cat, catmap) => new { Category = cat, CategoryMap = catmap })
select (c => c.Category)

这是使用 Linq to 实体的最佳实践,因为当您将 AsQueryable() 添加到代码中时;系统会将通用 System.Collections.Generic.IEnumerable 转换为通用 System.Linq.IQueryable,这对于 .Net 引擎在运行时构建此查询更有利

谢谢Khumesh Kumawat先生

于 2013-11-03T15:42:04.543 回答
0

您只需使用 yourSkip(itemsInPage * pageNo).Take(itemsInPage)来进行分页。

于 2012-04-19T05:56:27.913 回答