我有一个类似
的商品类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
选择前一个商品。
示例:如果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 };
}
}
问题:有没有办法用一个查询解决这个问题,而不是两次查询数据库?
答案 0 :(得分:2)
//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 };
答案 1 :(得分:2)
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);
答案 2 :(得分:0)
我不是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;
});
答案 3 :(得分:0)
您可以尝试这样的事情:
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;
答案 4 :(得分:0)
这可以通过子查询和投射到匿名类型来完成,例如:
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();