C# Linq處理list數據


獲取數據列表。

//獲取數據列表,Model是類
IList<Model> list = dao.getmx(Model, pageInfo);//DataTable數據
DataTable dt = ......;
 

1、GroupBy與group by

//GroupBy
//單條件,並返回序列中滿足指定條件的第一個元素(相當於list按照user_type去重,可以是多條).
list = list.GroupBy(a => a.user_type).Select(it => it.First()).ToList();

//多條件,使用了匿名函數.
var quary = list.Where(a => a.p_num == "1" || a.c_num == "1")
            .GroupBy(a => new { student_id = a.student_id, user_type = a.user_type })
            .Select(group => new
            {
                student_id = group.Key.student_id,
                user_type = group.Key.user_type,
                Count = group.Count()
            });

//group by
//單條件
var quary = from a in list.Where(a => "1,8".Contains(a.user_type))
            group a by new { a.school } into m
            select new
            {
                school = m.Key.school
            };

//多條件
var quary = from a in list.Where(a => "1,8".Contains(a.user_type))
            group a by new { a.provice, a.school } into m
            select new
            {
                provice = m.Key.provice,
                school = m.Key.school
            };

//quary取值方法,此處可寫可不寫ToList()。  
//經過測試,數據30W,無ToList()比ToList()的耗時少幾百毫秒,具體原因未知。下面是實驗的幾組數據:第一次9689 9398,第二次13529 10458,第三次10772 10392,第四次11370 10833。實際差距並不大。
foreach (var item in quary.ToList())
{
    //取值item
}
 

2、Where條件篩選。

//將provice=吉林的篩選出來。
list = list.Where(x => x.provice == "吉林").ToList();

//將包含1,5條件的數據篩選出來,相當於sql里的in用法:select * from 表 where user_type in (1,5)
list= list.Where(a => "1,5".Contains(a.user_type)).ToList();

//此處等同於上面
list= list.Where(a => a.user_type == "1" || a.user_type == "5").ToList();

//另一種形式,from開頭
IList<Model> query = (from item in list
                      where ("," + projectmodel.ids + ",").Contains("," + item.id + ",")
                      select item).ToList<Model>();

 

3、Select(取list中的id列數據,並按逗號分隔成字符串。例:1,2,3,4,5)

//方式一
//分成key-value的數組
string[] id = list.Select(a => a.id.ToString()).ToArray();
//dt是datatable類型的,執行LINQ語句,這里的.AsEnumerable()是延遲發生,不會立即執行,實際上什么都沒有發生
string[] id = dt.AsEnumerable().Select(a => a.Field<int>("id").ToString()).ToArray();
//將數組變成1,2,3,4,5的字符串
string ids = string.Join(",", id);

//方式二
//效果等同於foreach循環
foreach (var i in list)
{
    ids += i.id + ",";
}
ids = ids.TrimEnd(',');

上述代碼使用LINQ 針對數據集中的數據進行篩選和整理,同樣能夠以一種面向對象的思想進行數據集中數據的篩選。
在使用LINQ 進行數據集操作時,LINQ 不能直接從數據集對象中查詢,因為數據集對象不支持LINQ 查詢,所以需要使用AsEnumerable 方法返回一個泛型的對象以支持LINQ的查詢操作。

.AsEnumerable()與相對應的.AsQueryable()的區別:
1) AsEnumerable()是 LINQ TO OBJECT,AsQueryable()是 LINQ TO SQL
2) AsEnumerable將一個序列向上轉換為一個IEnumerable, 強制將Enumerable類下面的查詢操作符綁定到后續的子查詢當中。AsQueryable將一個序列向下轉換為一個IQueryable, 它生成了一個本地查詢的IQueryable包裝。
3) AsEnumerable()延遲執行,不會立即執行。當你調用.AsEnumerable()的時候,實際上什么都沒有發生。當真正使用對象的時候(例如調用:First, Single, ToList....的時候)才執行。
4) .ToList()立即執行

 

4、Where與Select的同時使用,取list中的id列數據,並按逗號分隔成字符串。

string[] id = list.Where(a => !string.IsNullOrEmpty(a.user_type)).Select(a => a.id).ToArray();
//ids="1,2,3,4,5,6,7";
string ids = string.Join(",", id);

 

5、左聯與內聯(例子是DataTable類型)

//dt,dt1,dt2都為DataTable類型。
//左聯比內聯,需要多寫into,需要多寫from gc1 in corr.DefaultIfEmpty(),需要多寫corr=gc1。
//當on為單條件時。
var results = from student in dt.AsEnumerable()
              join user in dt1.AsEnumerable() on student.Field<int>("student_id") equals user.Field<int>("id")//內聯
              join corr in dt2.AsEnumerable() on student.Field<int>("id") equals corr.Field<int?>("studentproject_id") into corr//左聯
              from gc1 in corr.DefaultIfEmpty()
              select new
              {
                  student,
                  user,
                  corr = gc1
              };

//當on為多條件時,借助於匿名類型:其實和解決按多條件分組的思路是一樣的。
var results = from student in dt.AsEnumerable()
              join zrs in result_zrs on new { districtcounty = student.Field<string>("districtcounty"), school = student.Field<string>("school") }
              equals new { districtcounty = zrs.districtcounty, school = zrs.school } into zrs
              from gc1 in zrs.DefaultIfEmpty()
              select new
              {
                  student,
                  corr = gc1
              };

//取值方式
foreach (var i in results.ToList())
{
    name = i.user.Field<string>("name");
}

 

6、OrderBy排序

//1個排序
list.OrderBy(a => a.student_id);
//2個排序
list.OrderBy(a => a.student_id).ThenBy(a => a.name);
//多個排序
list.OrderBy(a => a.student_id).ThenBy(a => a.name).ThenBy(a => a.sex);
//參數排序
List<string> liststr = new List<string>();
liststr.Add("aaa");
liststr.Add("bbb");
liststr.Add("ccc");
liststr = liststr.OrderBy(a => a).ToList();//aaa bbb ccc
liststr = liststr.OrderBy(a => a == "bbb" ? "1" : a == "ccc" ? "2" : "3").ToList();//bbb ccc aaa

 

7、OrderBy隨機排序

//方式一
Random rd = new Random();

List<string> liststr = new List<string>();
liststr.Add("aaa");
liststr.Add("bbb");
liststr.Add("ccc");
liststr.Add("111");
liststr.Add("222");
liststr.Add("333");
//隨機一個
var s = liststr.OrderBy(_ => Guid.NewGuid()).First();
//隨機兩個
var ss = liststr.OrderBy(_ => Guid.NewGuid()).Take(2);
//亂序
var sss = liststr.OrderBy(o => rd.Next(0, liststr.Count())).ToList();

 

//方式二
Random rd = new Random();
list.OrderBy(_=>rd.Next(1,99)).First();
//隨機排序通用方法
//就是從原List中每次隨機取一項,添加到新的List中,並在原List中刪除。這樣重復,直到原List為空為止。
//不過要注意,如果要保護原List不受變化,就必須先Copy一份List,再在Copy上進行操作
public static List<T> GetRandomList<T>(List<T> inputList)
{
    //Copy to a array
    T[] copyArray = new T[inputList.Count];
    inputList.CopyTo(copyArray);

    //Add range
    List<T> copyList = new List<T>();
    copyList.AddRange(copyArray);

    //Set outputList and random
    List<T> outputList = new List<T>();
    Random rd = new Random(DateTime.Now.Millisecond);

    while (copyList.Count > 0)
    {
        //Select an index and item
        int rdIndex = rd.Next(0, copyList.Count - 1);
        T remove = copyList[rdIndex];

        //remove it from copyList and add it to output
        copyList.Remove(remove);
        outputList.Add(remove);
    }
    return outputList;
}
 

8、Skip,Take分頁(LINQ:使用Take和Skip實現分頁)

//Skip是起始數據,表示從第n+1條數據開始.(此處pageNum應從0開始)
//pageNum:頁數、=0是第一頁,pageSize:一頁多少條
list = list.Skip(pageNum * pageSize).Take(pageSize).ToList();
//取前1-10條
list = list.Skip(0).Take(10).ToList();
//也可以這么寫取前1-10條
list = list.Take(10).ToList();
//取第11-20條
list = list.Skip(10).Take(10).ToList();

 

9、Distinct去重

//字符串數組
string[] idlist =  new string[ ]{"aaa","bbb","aaa"};
//去除重復aaa
idlist = idlist.Distinct().ToArray();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM