[英]Get current and previous Item with Linq
我有一個類似的優惠課程
public class Offer
{
public int OfferID { get; set; }
public DateTime OfferDate { get; set; }
public int CustomerID { get; set; }
}
現在我有很多這樣的報價
List<Offer> oList = new List<Offer>();
oList.Add(new Offer() { OfferID = 1, OfferDate = new DateTime(2018, 01, 01), CustomerID = 1 });
oList.Add(new Offer() { OfferID = 2, OfferDate = new DateTime(2018, 01, 03), CustomerID = 1 });
oList.Add(new Offer() { OfferID = 3, OfferDate = new DateTime(2018, 01, 01), CustomerID = 2 });
oList.Add(new Offer() { OfferID = 4, OfferDate = new DateTime(2018, 01, 05), CustomerID = 2 });
oList.Add(new Offer() { OfferID = 5, OfferDate = new DateTime(2018, 01, 02), CustomerID = 1 });
我想按ID來獲取要約,還要按日期來獲取該客戶的先前要約。
目前,我正在使用Linq2SQL並進行兩個選擇。 首先,我通過ID選擇所需的要約,然后通過OfferDate
選擇前一個OfferDate
。
示例:在OfferID==5
的情況下,此客戶的先前報價為OfferID==1
。
public List<Offer> GetCurrentAndPrevious(int OfferID)
{
using (DataContext cx = new DataContext())
{
Offer oCurrent = cx.Offer.Single(x => x.OfferID = OfferID);
Offer oPrevious = cx.Offer.OrderBy(x => x.OfferDate)
.Last(x => x.CustomerID = oCurrent.CustomerID && x.OfferDate < oCurrent .OfferDate);
return new List<Offer>() { oCurrent , oPrevious };
}
}
問題:是否可以通過一個查詢而不是兩次查詢數據庫來解決此問題?
//query syntax
var data = (from curr in cx.Offer.Where(x => x.OfferID == OfferID)
from prev in cx.Offer
where curr.CustomerID == prev.CustomerID && curr.OfferDate >= prev.OfferDate
orderby prev.OfferDate descending
select prev).Take(2).ToList();
//fluent syntax
data = cx.Offer.Where(x => x.OfferID == OfferID)
.Join(cx.Offer, curr => 0, prev => 0, (curr, prev) => new { curr, prev })
.Where(x => x.curr.CustomerID == x.prev.CustomerID && x.curr.OfferDate >= x.prev.OfferDate)
.OrderByDescending(x => x.prev.OfferDate)
.Select(x => x.prev).Take(2).ToList();
return new List<Offer>() { data.FirstOrDefault(), data.Count == 2 ? data.Last() : null };
var q = (from c in cx.Offer where c.OfferID == OfferID
from p in cx.Offer
where p.OfferDate <= c.OfferDate &&
p.CustomerID == c.CustomerID
orderby p.OfferDate descending
select p).Take(2);
我不是linq專家,所以也許其他答案更好,但這是lamba語法選項:
var currentAndPreviousOffers = oList.Where(offer =>
{
var current = oList.Single(o => o.OfferID == offerID);
var previous = oList
.Where(o => o.CustomerID == current.CustomerID && o.OfferDate < current.OfferDate)
.OrderByDescending(o => o.OfferDate).First();
return offer.OfferID == current.OfferID || offer.OfferID == previous.OfferID;
});
您可以嘗試如下操作:
var offers = from u in oList
join c in (
from crt in oList
where crt.OfferID == OfferID
orderby crt.OfferDate
select crt)
on u.CustomerID equals c.CustomerID
where u.OfferID == OfferID || u.OfferDate < c.OfferDate
select u;
這可以通過子查詢並通過投影為匿名類型來完成,例如:
var currentAndPrevious = dataContext.Offer
.Where(x => x.OfferID == OfferID)
.Select(x =>
new
{
Current = x,
Previous = dataContext.Offer.OrderByDescending(y => y.OfferDate).Where(y => y.OfferDate < x.OfferDate && y.CustomerID == x.CustomerID).FirstOrDefault()
})
.FirstOrDefault();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.