我正在C#开发一个项目。我有一个名为ExamResult
的模型,其中有一个名为Date
的字段,定义为String
。
然后我定义以下
var executionQuery = (from x in db.ExamResult
where x.Student.Equals(iStudent)
orderby x.Date
select *);
日期以<YEAR>-<MONTH>
格式获取值
像这样
2014-01
2013-04
2013-09
我想要做的是创建一个表,该表获取所有返回日期的最小值,并创建一个与该最小日期相差几个月的表。
示例:
当我们得到上述结果时,我想得到下表(如果我们得到的最小值是2013-04)
9
0
5
我尝试执行以下操作,但收到System.NotSupported
异常
var dates = executionQuery.Select(x => int.Parse(x.Date.Substring(0,
4)) * 12 + int.Parse(x.Date.Substring(5, 2)) -
int.Parse(minDate.Substring(0, 4)) * 12 -
int.Parse(minDate.Substring(5, 2)));
你知道我怎么做吗?
答案 0 :(得分:3)
将字符串转换为实际的'DateTime'对象会使事情变得更简单。
// Getting DateTime objects instead of strings
var dates = executionQuery.ToArray().Select(
x => DateTime.ParseExact(x.Date,"yyyy-MM", CultureInfo.InvariantCulture));
// calculating smallest date
var minDate = dates.Min(x => x);
// this will help you get a collection of integers
var diffDates = dates.Select(
x => ((x.Year - minDate.Year) * 12) + x.Month - minDate.Month);
答案 1 :(得分:3)
我会使用一个小Func<TIn, TOut>
委托将您的字符串日期转换为DateTimes,然后可以对它们进行正确排序。
首先,将日期字符串转换为DateTime
对象的简单方法:
// Split the string and instantiate new DateTime object to sort by later
Func<string, DateTime> getDate = s => {
int[] dateParts = s
.Split(new char[] {'-'})
.Select(dp => int.Parse(dp))
.ToArray();
// Let's use the new DateTime(int year, int month, int day) constructor overload
// dateParts[0] is the year and dateParts[1] is the month;
// the magic number 1 below is just a day to give to the DateTime constructor
return new DateTime(dateParts[0], dateParts[1], 1);
};
您的代码可能看起来像这样;我无法测试您的代码,因此这取决于您的工作:
注意我将Linq
查询分开,并在C#中进行排序;所以你可以随心所欲地从数据库中获取东西,然后订购这些东西。我希望这有效;否则,您必须拨打我的getDate
Func
两次 - 一次在orderby
上,一次在select
上;我不喜欢那个选项。
// The select now builds an anonymous object; You can also create a new class, ExamResultWithDate,
// for example, that has all fields of ExamResult plus a DateTime field; OR you can just add that
// property to the partial class generated by EF or Linq-to-Sql or whatever right on the ExamResult
// entity.
var executionQuery = (from x in db.ExamResult
where x.Student.Equals(iStudent)
select new { Entity = x, ActualDate = getDate(x.Date) }); // note select * as in your OP doesn't compile :)
var orderedQuery = executionQuery
.OrderBy(eq => eq.ActualDate)
.Select(er => er.Entity); // gets you just the entities in this case and discards the dates
要获得有差异的日期,只需在最短的日期进行一些简单的计算: 这又是你程序的伪代码;
// Let's get the minimum date and difference in months;
DateTime minDate = executionQuery
.ToList()
.Select(o => o.ActualDate)
.Min();
// I am just using the dates here but you can easily use your entire entity or whatever you need
Dictionary<DateTime, int> datesWithMonthDifference = executionQuery
.ToDictionary(
eq => eq.ActualDate
eq => ((eq.Year - minDate.Year) * 12) + eq.Month - minDate.Month // this formula calculates month difference as an integer
);
这是一个可以满足您需求的工作程序: 请注意,这只是一个需要适合您的项目的示例。
using System;
using System.Collections.Generic;
using System.Linq;
namespace DateTimeFromString
{
class Program
{
static void Main(string[] args)
{
List<string> dates = new List<string>()
{
"2014-01",
"2013-04",
"2013-09"
};
// Split the string and instantiate new DateTime object to sort by later
Func<string, DateTime> getDate = s => {
int[] dateParts = s
.Split(new char[] {'-'})
.Select(dp => int.Parse(dp))
.ToArray();
// Let's use the new DateTime(int year, int month, int day) constructor overload
// dateParts[0] is the year and dateParts[1] is the month;
// the magic number 1 below is just a day to give to the DateTime constructor
return new DateTime(dateParts[0], dateParts[1], 1);
};
List<DateTime> sortedDates = dates
.Select(d => getDate(d))
.OrderBy(d => d)
.ToList();
Console.WriteLine(" Sorted Dates: ");
sortedDates.ForEach(d => Console.WriteLine(d.Year.ToString() + " - " + d.Month.ToString()));
// Let's get the minimum date and difference in months;
DateTime minDate = sortedDates.Min();
Dictionary<DateTime, int> datesWithMonthDifference = sortedDates
.ToDictionary(
sd => sd,
sd => ((sd.Year - minDate.Year) * 12) + sd.Month - minDate.Month
);
Console.WriteLine();
Console.WriteLine("Sorted dates with month difference:");
foreach (var key in datesWithMonthDifference.Keys)
{
Console.WriteLine("{0} has difference of {1}", key, datesWithMonthDifference[key]);
}
Console.ReadKey();
}
}
}
我的测试程序的结果如下: