0

コストが最初に発生する時期と、コストが何度も発生することを意味する繰り返し期間を年単位で指定したいと考えています。そこで、次のようなコスト モデルを作成しました。

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 を使用して、2 つの日付の間に発生したコストを返したいと考えています。

編集質問を単純化しすぎました。特定の日付と一定期間後に発生した 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

    }
4

2 に答える 2

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

これは簡単な修正であり、のイニシャル0Enumerable.Range計算に置き換えることができます。

于 2013-08-23T15:58:44.377 に答える
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);
    }
}
于 2013-08-20T09:34:16.650 に答える