已知: 一个等级实体 public class Levels { public string ID { get; set; } //编号 public string Name { get; set; } //名称
public int No {get;set;}//排名
} List<Levels> li = new List<Levels>(); li.Add(new Levels { ID = "A", Name = "一般" }); li.Add(new Levels { ID = "B", Name = "严重" }); li.Add(new Levels { ID = "C", Name = "紧急" });
li.Add(new Levels { ID = "D", Name = "危急" }); 一个数据实体 public class Data { public string DID { get; set; }//编号 public string LID { get; set; }//等级编号(关联Levels中的ID) public int Num { get; set; }//次数 } List<Data> dli = new List<Data>(); dli.Add(new Data { DID = "1", LID = "A", Num = 5 });
dli.Add(new Data { DID = "2", LID = "B", Num = 3 });
dli.Add(new Data { DID = "3", LID = "C", Num = 3 });
问题:需要根据等级进行次数统计,然后排名(注:1.次数相同排名相同;2.没有出现的等级次数为0,最后也要出现排名)
{linq语句}
结果:
排名 等级 次数
1 一般 5
2 严重 3
2 紧急 3
3 危急 0
修改了一些需求内容,这样应该明白了吧
var levels = li; var datas =dli; var distinctDatas = datas.Select(n => n.Num).Distinct().OrderByDescending(n => n).ToList(); var paiming = from c in levels join d in datas on c.ID equals d.LID into temp from tt in temp.DefaultIfEmpty() let no = (tt == null ? distinctDatas.Count + 1 : distinctDatas.IndexOf(tt.Num) + 1) let num = (tt == null ? 0: tt.Num) select new { no, c.ID,num };
膜拜一下,Good~!!
根据我目前掌握的知识,提供以下建议:
1、想要用一条LINQ语句实现需求,应该是比较难或者说不太可能的。
2、需求仍然不够明确,比如第2名相同的有2个,第3名要写第3还是第4?
3、我目前知道的,只能用代码,循环语句,当然,性能问题另外考虑。
4、如果想要一句LINQ实现,建议是否可以修改需求,比如相同次数,随机排名。就是有的第2名,有的第3名。
5、就你的问题而言,LEVELS类在这个问题里面没有任何用处。
因为你要的结果是"A",而不是"一般"。所以就算有LINQ语句能够完成需求,也不需要LEVELS这个类。也就是说你提供了额外而无用的信息。
如果想要实现得简单一点,最好把两个实体类中的一个实体类作为另一个实体类的属性。
毕竟他们之间是有关系的,所以还是建立关系。
List<Levels> li = new List<Levels>(); li.Add(new Levels { ID = "A", Name = "一般" }); li.Add(new Levels { ID = "B", Name = "严重" }); li.Add(new Levels { ID = "C", Name = "紧急" }); List<Data> dli = new List<Data>(); dli.Add(new Data { DID = "1", LID = "A", Num = 2 }); dli.Add(new Data { DID = "2", LID = "B", Num = 2 }); dli.Add(new Data { DID = "3", LID = "C", Num = 5 }); var result = (from leve in li join data in dli on leve.ID equals data.LID orderby data.Num descending select new { leve.ID, data.Num, } ).ToList(); var ordery =result.ToArray(); int count = 1; List<Result> oResults = new List<Result>(); for (int i = 0; i < ordery.Length; i++) { //确定是否到数组边界 if (i + 1 < ordery.Length) { //如果与list中下一位的Num数相等则 排名Count数不变 if (ordery[i].Num == ordery[i + 1].Num) { var item = new Result {id = count, Name = ordery[i].ID, Num = ordery[i].Num}; oResults.Add(item); } else { //如果与list中下一位的Num数不相等则 排名Count加1 var item = new Result { id = count, Name = ordery[i].ID, Num = ordery[i].Num }; oResults.Add(item); count++; } } //如果是最后一位了就直接添加 else { var item = new Result { id = count, Name = ordery[i].ID, Num = ordery[i].Num }; oResults.Add(item); } } foreach (var i in oResults) { Console.WriteLine(i.id+"--"+i.Name+"--"+i.Num); } Console.Read(); } } public class Levels { public string ID { get; set; } //编号 public string Name { get; set; } //名称 public int No { get; set; }//排名 } public class Data { public string DID { get; set; }//编号 public string LID { get; set; }//等级编号(关联Levels中的ID) public int Num { get; set; }//次数 } public class Result { public int id { get; set; } //排名Id public string Name { get; set; }//名称 public int Num { get; set; }//次数 }
中午闲着没事儿干,然后就写了写,主要是排名那有点麻烦,而且我觉得这种实现方法不科学...............先睡觉了.
你被楼主误导了。LEVELS类在这儿根本没有用处。
按照你的写法,给建议如下:
1、 var query = from c in dli
order by c.num
select c.lid, c.num
这样就够了,多余还要去连接LEVELS类。