我正在进行LINQ查询以获取数据库,年龄和日期的2个字段中的所有值。我想在图表上显示5个最高年龄数字。为此,我试图将年龄和日期存储在2个单独的列表,ageList和dateList中。
最初在比较每个List中的索引与索引的值时,与年龄和日期的关系是正确的。例如:
存储在ageList.ElementAt(0)的年龄将是dateList.ElementAt(0)日期的正确值。
但是由于我要获得5个最高年龄数字,我需要排序年龄列表。通过这样做,我将失去两个列表之间的匹配。
我尝试将数据存储在SortedDictionary中,而不是Key为age,Value为date。问题是它不允许重复键。在我的情况下,我需要重复键,因为多个年龄可以相同,日期也可以相同。
这有什么办法吗?
我的代码尝试使用Dictionary存储。它在存储重复的密钥时会抛出异常。
//Linq query
var xChartData = from x in db.Person
select new { x.Age, x.Date };
SortedDictionary<double, DateTime> topAgeDict = new SortedDictionary<double, DateTime>();
//Storing in Dictionary
foreach (var x in xChartData)
{
topAgeDict.Add(x.Age, x.Date); //Exception caused when repeated values
}
Dictionary<string, string> stringDict = new Dictionary<string, string>();
//store data as string for chart purposes
foreach (var x in topAgeDict)
{
stringDict.Add(x.Key.ToString(), x.Value.ToString());
}
List<string> ages = new List<string>();
List<string> dates = new List<string>();
//storing the dictionary key and value in List for element access.
ages = stringDict.Keys.ToList();
dates = stringDict.Values.ToList();
//to store only the top 5 results. This will be the data used in chart.
List<string> topFiveAge = new List<string>();
List<string> topFiveDate = new List<string>();
for (int x=1; x <= 5; x++)
{
topFiveAge.Add(ages.ElementAt(ages.Count - x));
topFiveDate.Add(dates.ElementAt(dates.Count - x));
}
//Chart
var topAgefilePath = Server.MapPath("~/Chart_Files/topAge.jpg");
if (System.IO.File.Exists(topAgefilePath))
{
System.IO.File.Delete(topAgefilePath);
}
var ageChart = new Chart(580, 400);
ageChart.AddTitle("Top Age");
ageChart.AddSeries(
chartType: "column",
xValue: topFiveDate,
yValues: topFiveAge
);
ageChart.Save(topAgefilePath);
答案 0 :(得分:2)
// top 5 oldest persons
var xChartData = (from x in db.Person
order by x.Age descending
select new { x.Age, x.Date })
.Take (5);
我认为没有理由把它分成两个List<>
s
答案 1 :(得分:2)
你应该真正创建具体的类型,因为你将这种类型提供给某种类型的控件。
public class PersonAgeDateItem
{
public string Age {get;set;} // should be an int though..
public DateTime Date {get;set;}
}
获取数据的Lambda版本;
请注意,我在此处使用匿名object
个实例,然后在Select
之后执行PersonAgeDateItem
。此实现不会受益于匿名对象实例,但是以对象比较的形式存在一些好处考虑因素(而不是在IEqualityComparer<T>
上实现PersonAgeDateItem
,overriding
{{1} }和GetHashCode
),如果您最终添加Object.Equals
GroupBy
...或任何类似的情景......
Distinct
然后我们为var data = db.Person.Select(person => new { Age = person.Age, Date = person.Date })
.OrderByDescending(person => person.Age)
.Take(5)
.Select(person => new PersonAgeDateItem() {
Age = person.Age,
Date = person.Date
});
// person.Age, being a string, could pose an issue.. like "2" coming after "19", "199", "1999".. etc etc
,Select
初始化执行另一个xValue
。
yValue
答案 2 :(得分:1)
您可以使用Dictionary
来保存年龄和日期列表,而不是List<Tuple<double, DateTime>>
。
var ageAndDate = from x in db.Person
select new Tuple<double, DateTime>(x.Age, x.Date);
var topFiveAgeWithdate = ageAndDate.OrderByDescending(t => t.Item1).Take(5).ToList();
List<string> topFiveAge = topFiveAgeWithdate.Select(t => t.Item1.ToString()).ToList();
List<string> topFiveDate = topFiveAgeWithdate.Select(t => t.Item2.ToShortDateString()).ToList();
可以使用Anonymous Type
s
var ageAndDate = from x in persons
select new { x.Age, x.Date };
var topFiveAgeWithdate = ageAndDate.OrderByDescending(t => t.Age).Take(5).ToList();
List<string> topFiveAge = topFiveAgeWithdate.Select(t => t.Age.ToString()).ToList();
List<string> topFiveDate = topFiveAgeWithdate.Select(t => t.Date.ToShortDateString()).ToList();