SQL to LINQ with Case .当按顺序

本文关键字:顺序 Case with to LINQ SQL | 更新日期: 2023-09-27 18:31:23

我有一个SQL查询,我想将其转换为LINQ查询,但不确定如何进行。我有两个实体ProductPrice.Price通过ProductId链接到Product。查询根据请求Product的数量获取产品的最佳价格。

例如:如果客户想要购买 10 件产品,则产品的价格可能为 5 美元/单位。但是,如果客户想要购买 100 个单位的产品,那么成本可能是 3 美元/单位。此查询将根据请求的数量获得最佳单价。WHERE 子句确保选择正确的产品,如果日期已过期,则排除任何价格。CASE 语句对价格进行排序,以便只要达到请求的数量,就会首先显示最佳价格。

Price Table
--------------------------
Id    ProductId      Quantity     Price    BeginDate   EndDate
=========================================================================
1     1234           10           $5       1/1/2016    2/1/2016
2     1234           100          $3       1/1/2016    2/1/2016
3     1234           100          $1       1/1/2016    1/9/2016
4     1234           500          $2       1/1/2016    2/1/2016

SELECT TOP 1
  Product.Id,
  Product.Name,
  Prices.Price
FROM Products INNER JOIN Prices ON Products.Id = Prices.ProductId
WHERE Product.Id = @ProductId
  AND ((Price.BeginDate IS NULL OR Price.BeginDate < GETDATE()) AND (Price.EndDate IS NULL OR Price.EndDate > GETDATE())) 
ORDER BY
  CASE WHEN Price.Quantity <= @RequestedQuantity THEN Price.Quantity 
   ELSE -Price.Quantity
  END

在 LINQ 中让我感到困惑的查询部分..

  1. 如何筛选出价格日期已过期的价格(例如 Id = 3)。
  2. 如何使用案例语句对集合进行排序。

一旦这些就位,我就可以使用 FirstOrDefault 选择顶部结果

SQL to LINQ with Case .当按顺序

尝试使用 let 关键字来定义列并对其进行排序。我没有测试它,我不确定它会像你期望的那样工作。对于示例,请确保在其上定义了所有实体和属性:

var query = from product in Products 
            join price in Prices on product.Id equals price.ProductId
            let priceOrder = price.Quantity <= requestValue ? price.Quantity : -price.Quantity 
            where ((price.BeginDate == null || Price.BeginDate < DateTime.Now) && (Price.EndDate == null || Price.EndDate > DateTime.Now))
            orderby priceOrder 
            select { product.Id, product.Name, price.Price };
var result = query.FirstOrDefault();

如果您使用的是实体框架

SELECT TOP 1
  Product.Id,
  Product.Name,
  Prices.Price
FROM Products INNER JOIN Prices ON Products.Id = Prices.ProductId
WHERE Product.Id = @ProductId
  AND ((Price.BeginDate IS NULL OR Price.BeginDate < GETDATE()) AND (Price.EndDate IS NULL OR Price.EndDate > GETDATE())) 
ORDER BY
  CASE WHEN Price.Quantity <= @RequestedQuantity THEN Price.Quantity 
   ELSE -Price.Quantity
  END

应该看起来像

var SelectedProduct = ObjectYourDatabaseIsLabeledAs.Products
    .FirstOrDefault(p => p.Id == ProductId) // Gets matching Ids

var SelectedProduct = ObjectYourDatabaseIsLabeledAs.Products.Find(ProductId)

然后得到合适的价格

var SelectedPrice = SelectedProduct?.Prices
    .OrderByDesc(o => o.Quantity) // Sets the highest number at the top of the IEnum
    .FirstOrDefault(p => // Take the first/default one where...
        p.EndDate >= DateTime.Today &&
        p.StartDate <= DateTime.Today && // Gets All With Valid Prices
        p.Quantity <= RequestedQuantity) // Removes all the high quantities that you don't want

这几乎是一对一的翻译。

.SQL

SELECT TOP 1 Product.Id, Product.Name, Prices.Price
FROM Products
INNER JOIN Prices ON Products.Id = Prices.ProductId
WHERE Product.Id = @ProductId
    AND (Price.BeginDate IS NULL OR Price.BeginDate < GETDATE())
    AND (Price.EndDate IS NULL OR Price.EndDate > GETDATE()) 
ORDER BY CASE WHEN Price.Quantity <= @RequestedQuantity THEN Price.Quantity ELSE -Price.Quantity END

林克

var productId = ...;
var requestedQuantity = ...;
var date = DateTime.Today;
var query = 
    (from product in db.Products
     join price in db.Prices on product.Id equals price.ProductId
     where product.Id == productId
         && (price.BeginDate == null || price.BeginDate < date)
         && (price.EndDate == null || price.EndDate > date)
     orderby price.Quantity <= requestedQuantity ? price.Quantity : -price.Quantity
     select new { product.Id, product.Name, price.Price }
    ).Take(1);
var result = query.FirstOrDefault();

唯一的区别是select排在最后,CASE WHEN condition THEN a ELSE b END映射到condition ? a : bTOP n变得.Take(n) .

实际上这里不需要Take(1),我将其包含在内只是为了进行比较,以防您需要TOP 10例如。