我有两张桌子:
表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表时,我在那里有所有属性,但我不能像上面的语句那样访问它们。 感谢任何帮助
答案 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();