如何使用Linq检索重复成本

时间:2013-08-20 09:16:39

标签: linq entity-framework

我想说明首次发生成本的时间和多年的重复周期,这意味着成本会一次又一次地发生。所以我创建了一个如下所示的Cost模型:

public class Cost
{
    public Cost()
    {
        Year = 1;
    }

    public decimal Amount { get; set; }

    public int AnsweredQuestionID { get; set;}

    public virtual AnsweredQuestion AnsweredQuestion {get; set;}

    public int? RepeatPeriod { get; set; }
}

现在我想要返回两个日期之间发生的费用,最好是使用Linq。

修改我过度简化了我的问题。我有在特定日期和一段时间后再次发生的PropertyCosts。首次发生费用的日期是从调查财产的日期算起的。成本模型存储RepeatPeriod并且与特定问题/答案相关。如果以特定方式回答房产问题,则会产生费用。所以我的代码看起来有点像这样(仍然试图在这里简化)但是目前我只是第一次出现

    public IEnumerable<PropertyCost> GetCosts(DateTime startDate, DateTime endDate)
    {
       IQueryable<AnsweredQuestion> answeredQuestions = 
                           _Uow.AnsweredQuestionRepository
                               .All
                               .Where(x => x.PropertySurvey.PropertyID == id);
       IQueryable<Cost> allCosts = UOW.CostRepository.All;

       IQueryable<PropertyCost> firstOccurences = from aq in answeredQuestions
              from c in costs
              where aq.ID == c.AnsweredQuestionID
              select new PropertyCost
              {
                  QuestionText = aq.Question.Text,
                  AnswerText = aq.Answer.Text,
                  UnitCost = c.Amount,
                  Date = aq.PropertySurvey.Survey.StartDate,
                  RepeatYears = c.RepeatPeriod
              });
       //but now I need to insert PropertyCosts for recurring costs that occur when RepeatPeriod is not null

    }

2 个答案:

答案 0 :(得分:1)

首先,我不知道您为什么要返回Cost项的集合。您应该创建另一个class来处理该数据,例如:

public class CostOccurrence
{
    public decimal Amount { get; set; }
    public DateTime Occurrence { get; set; }
}

然后实施您的方法:

public IEnumerable<CostOccurrence> GetCosts(DateTime startDate, DateTime endDate)
{
    DateTime current = FirstIncurred;

    while (current < startDate)
        current = current.AddYears(RepeatPeriod);

    while (current >= startDate && current < endDate)
    {
        yield return new CostOccurrence { Amount = Amount, Occurrence = current };
        current = current.AddYears(RepeatPeriod);
    }
}

答案 1 :(得分:1)

这个怎么样....

var costs = firstOccurences.SelectMany (p => 
           from x in Enumerable.Range(0, (p.RepeatYears ?? 0) > 0
                               ? ((endDate.Year - p.Date.Year)+1)/p.RepeatYears.Value
                               : 1)
        let date = p.Date.AddYears(x * p.RepeatYears??0)
        where startDate <= date && endDate >= date
        select new PropertyCost {
          QuestionText=p.QuestionText,
          AnswerText=p.AnswerText,
          UnitCost = p.UnitCost,
          Date = date,
          RepeatYears = p.RepeatYears
        }
    )

由于翻译功能

,您可能需要先将firstOccurences转换为Enumerable

例如

          IEnumerable<PropertyCost> firstOccurences = (from aq in answeredQuestions
          from c in costs
          where aq.ID == c.AnsweredQuestionID
          select new PropertyCost
          {
              QuestionText = aq.Question.Text,
              AnswerText = aq.Answer.Text,
              UnitCost = c.Amount,
              Date = aq.PropertySurvey.Survey.StartDate,
              RepeatYears = c.RepeatPeriod
          }).AsEnumerable();

这是一个快速解决方案,0的初始Enumerable.Range可以替换为计算。