访问包含实体框架

时间:2016-08-22 12:18:10

标签: asp.net-mvc entity-framework

我有两张桌子:

表1(销售):

Id   |    CustomerId

表2(SaleProduct):

Id   |    SaleId |     Quantity

我有以下声明:

var topSales = db.Sales.Include(c => c.SaleProducts).Where(p =>p.CustomerId == id);

我想对SaleProducts表进行排序,并根据SaleId外键选择5 top(按数量排序),其中CustomerId等于它在控制器方法中接收的id。 如何访问SaleProducts属性以执行以下操作:

var orderedItems = topSales.OrderByDescending(c => c.Quantity).Take(5);

当我包含SaleProducts表时,我在那里有所有属性,但我不能像上面的语句那样访问它们。 感谢任何帮助

2 个答案:

答案 0 :(得分:1)

您可以在访问SaleProducts属性时进行排序,并使用Take方法获取5个项目。

var prods2 = db.Sales.Include(c => c.SaleProducts)
               .Where(p =>p.CustomerId == id)
               .Select(g => new
                         {
                           SaleId = g.Id,
                           Products = g.SaleProducts.OrderByDescending(h => h.Quantity)
                                       .Take(5)
                                       .Select(x => new
                                                        {
                                                          Id = x.Id,
                                                          Quantity = x.Quantity

                                                         })
                        }).ToList();

以上代码将为您提供特定客户的销售额,并且每位客户仅包含前5个SaleProduct(按数量排序)

我将结果投影到匿名对象(new { })。如果您有视图模型,则可以将投影更改为。

public class SaleVm
    {
        public int Id { set; get; }
        public int CustomerId { set; get; }
        public List<SaleProductVm> SaleProducts { set; get; }
}

public class SaleProductVm
{
        public int Id { set; get; }
        public int SaleId { set; get; }
        public int Quantity { set; get; }
}

只需用这些类替换匿名对象投影

List<SaleVm> prods2 = db.Sales.Include(c => c.SaleProducts)
                        .Where(p =>p.CustomerId == id)
                        .Select(g => new SaleVm
                         {
                           SaleId = g.Id,
                           Products = g.SaleProducts.OrderByDescending(h => h.Quantity)
                                       .Take(5)
                                       .Select(x => new SaleProductVm
                                                        {
                                                          Id = x.Id,
                                                          Quantity = x.Quantity  
                                                         })
                        }).ToList();

答案 1 :(得分:1)

这里有两个选项:

第一个选项。

尝试查询SaleProduct表而不是Sale表和Include Sale

var topSaleProducts = db.SaleProducts
    .Where(m => m.Sale.CustomerId == id)
    .Include(m => m.Sale)
    .OrderByDescending(m => m.Quantity)
    .Take(5);

现在您已根据CustomerId拥有前5个促销产品,并且Sale也会被加载。

第二个选项。

您可以在加载Sale后使用显式加载来获得前5个SaleProducts。请记住,您将通过以下方式查询数据库两次:

// Load the sale first
var topSale = db.Sales.First(m => m.CustomerId == id);

// Then load SaleProducts using Explicit loading.
db.Entry(topSale)
    .Collection(m => m.SaleProducts)
    .Query()
    .OrderByDescending(m => m.Quantity)
    .Take(5)
    .Load();