我有一个SQL查询,我想转换成LINQ查询,但我不知道如何继续。我有两个实体Product
和Price
。 Price
与Product
ProductId
相关联。该查询根据所请求的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中感到困惑..
一旦这些到位,我就可以使用FirstOrDefault
答案 0 :(得分:3)
尝试使用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();
答案 1 :(得分:2)
如果您使用的是实体框架
DhtListener listener = new DhtListener(new IPEndPoint(IPAddress.Parse("192.168.2.3"), 10000));
应该看起来像
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)
答案 2 :(得分:1)
这是一对一的翻译。
<强> 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
<强> LINQ 强>
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 : b
,TOP n
变为.Take(n)
。
实际上这里不需要Take(1)
,我只是为了比较而将其包含在内,以备你需要TOP 10
时使用。