使用Linq获取当前和之前的项目

时间:2018-04-11 06:48:56

标签: c# entity-framework 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选择前一个商品。

示例:如果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 };
    }
}

问题:有没有办法用一个查询解决这个问题,而不是两次查询数据库?

5 个答案:

答案 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();