using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Data; using System.Data.SqlTypes; using System.Data.Common; using Xunit; using LinqStudy.IEnumerableDemo; namespace LinqStudy.Test.LinqToObject { /// /// 转换运算符 /// public class TypeConvertTest { #region AsEnumeralbe /// /// AsEnumeralbe操作符:将IEnumerable输入序列转换成IEnumerable的输出序列 /// 主要用于将一个实现了IEnumerable接口的对象转换成一个标准的IEnumerable接口对象。 /// 在Linq中、不同领域的Linq实现都有自己专属的操作符。 /// [Fact] public void AsEnumeralbe_Test() { var dt = GetDataTable(); //DataTable 使用方法,须有添加 System.Data.DataSetExtensions 引用 var students = dt.AsEnumerable().FirstOrDefault(); Assert.NotNull(students); } #endregion #region AsQueryable /// /// 主要应用与Linq to sql /// [Fact] public void AsQueryable_Test() { // } #endregion #region OfType /// /// OfType:从序列中筛选指定类型的元素,并构建一个序列。 /// [Fact] public void OfType_Test() { //动态数组做为数据源 ArrayList ints = new ArrayList() { 1, "2", 3, "4", 5 }; var values = from i in ints.OfType() select i; Assert.Equal(new List() { 1, 3, 5 }, values.ToList()); } #endregion #region Cast /// /// Cast:将数据源中元素,强制转换成指定的类型。 /// 数据源null或存在不能转换的元素,则异常。 /// [Fact] public void Cast_Test() { //动态数组做为数据源 ArrayList ints = new ArrayList() { "1", "2", "3", "4", "5" }; var values = ints.Cast(); Assert.Equal(new List() { "1", "2", "3", "4", "5" }, values.ToList()); } [Fact] public void Cast_ArgumentNullException_Test() { //动态数组做为数据源 ArrayList ints = null; Assert.Throws(() => { ints.Cast(); }); } [Fact] public void Cast_InvalidCastException_Test() { //动态数组做为数据源 ArrayList ints = new ArrayList() { 1, "2", 3, "4" }; Assert.Throws(() => { ints.Cast().ToList(); }); } #endregion #region ToList /// /// ToList:将IEnumerable转换为List, 立即执行。 /// 特别注意:此操作破坏"延迟执行",变为立即执行; /// 结果为数据源的一个快照,独立保存在内存中,不 受数据源变化的影响。 /// [Fact] public void ToList_Test() { List email = new List() { "abc@163.com", "bcd@126.com", "111@163.com" }; var query = email.Where(q => q.Contains("@163.")).ToList(); Assert.Equal(new List() { "abc@163.com", "111@163.com" }, query); } [Fact] public void ToList_DataSource_Change_Test() { List email = new List() { "abc@163.com", "bcd@126.com", "111@163.com" }; //延迟执行机制 var query1 = email.Where(q => q.Contains("@163.")); //ToList 变成立即执行,保存数据源的一个“快照” var query2 = email.Where(q => q.Contains("@163.")).ToList(); //数据源变化 email.Add("test@163.com"); //延迟执行,反映数据源变化 Assert.Equal(new List() { "abc@163.com", "111@163.com", "test@163.com" }, query1.ToList()); //ToList,不受数据源变化影响 Assert.Equal(new List() { "abc@163.com", "111@163.com" }, query2); } /// /// 引用类型的数据源,ToList之后形成的新序列是数据源的“完全新副本”的新对象。 /// 数据源与新序列元素的引用,不是同一个对象。 /// [Fact] public void ToList_ReferenceType_DataSource_Test() { List persons = PersonManager.GetPersons(); var person2 = persons.ToList(); //元素对象不是同一个元素 Assert.NotSame(persons, person2); } #endregion #region ToDictionary /// /// ToDictionar转换字典,立即执行并保存快照。 /// [Fact] public void ToDictionary_keySelector_Test() { List persons = new List() { new Person() {Id=1, Name="gaofeng",Age = 32 }, new Person() {Id=2, Name="zhangsan",Age = 25 }, }; var dic = persons.ToDictionary(p => p.Id); Assert.Equal(1, dic[1].Id); Assert.Equal(2, dic[2].Id); } [Fact] public void ToDictionary_keySelector_comparer_Test() { List persons = new List() { new Person() {Id=1, Name="gaofeng",Age = 32 }, new Person() {Id=2, Name="zhangsan",Age = 25 }, }; var dic = persons.ToDictionary(p => p.Id, EqualityComparer.Default); Assert.Equal("gaofeng", dic[1].Name); Assert.Equal("zhangsan", dic[2].Name); } [Fact] public void ToDictionary_keySelector_elementSelector_Test() { List persons = new List() { new Person() {Id=1, Name="gaofeng",Age = 32 }, new Person() {Id=2, Name="zhangsan",Age = 25 }, }; var dic = persons.ToDictionary(p => p.Id, s => s.Name); Assert.Equal("gaofeng", dic[1]); Assert.Equal("zhangsan", dic[2]); } [Fact] public void ToDictionary_keySelector_elementSelector_comparer_Test() { List persons = new List() { new Person() {Id=1, Name="gaofeng",Age = 32 }, new Person() {Id=2, Name="zhangsan",Age = 25 }, }; var dic = persons.ToDictionary(p => p.Id, s => s.Name, EqualityComparer.Default); Assert.Equal("gaofeng", dic[1]); Assert.Equal("zhangsan", dic[2]); } [Fact] public void ToDictionary_ArgumentException_Test() { List persons = new List() { new Person() {Id=1, Name="gaofeng",Age = 32 }, new Person() {Id=1, Name="zhangsan",Age = 25 }, }; Assert.Throws(() => { persons.ToDictionary(p => p.Id, s => s.Name); }); } [Fact] public void ToDictionary_ArgumentNullException_Test() { List persons = new List() { new Person() {Id=1, Name=null,Age = 32 }, new Person() {Id=1, Name="zhangsan",Age = 25 }, }; Assert.Throws(() => { persons.ToDictionary(p => p.Name, s => s.Name); }); } [Fact] public void ToDictionary_DataSource_NullException_Test() { List persons = null; Assert.Throws(() => { persons.ToDictionary(p => p.Name, s => s.Name); }); } #endregion #region ToLookup /// /// ToLookup:根据指定的键选择器函数从IEnumerable创建Lookup /// Lookup对象表示一个一对多的字典,定义了一个由键和序列组成的元组,类似GroupJoin返回的结果。 /// [Fact] public void ToLookup_Test() { var persons = new List() { new Employee(){ Id=1, Name="gaofeng",Emails=new List(){"a1@163.com","a2@163.com","a3@163.com"} }, new Employee(){ Id=1, Name="zhangsan",Emails=new List(){ "b1@163.com", "b2@163.com", "b3@163.com" } }, new Employee(){ Id=2, Name="gaofeng2",Emails=new List(){"c1@163.com","c2@163.com","c3@163.com"} }, new Employee(){ Id=2, Name="zhangsan2",Emails=new List(){ "d1@163.com", "d2@163.com", "d3@163.com" } }, }; var lookup = persons.ToLookup(q => q.Id); var group2 = lookup[2]; var group2_count = group2.Count(); Assert.Equal(2,group2_count); } [Fact] public void ToLookup_keySelector_comparer_Test() { var persons = new List() { new Employee(){ Id=1, Name="gaofeng",Emails=new List(){"a1@163.com","a2@163.com","a3@163.com"} }, new Employee(){ Id=1, Name="zhangsan",Emails=new List(){ "b1@163.com", "b2@163.com", "b3@163.com" } } }; var lookup = persons.ToLookup(q => q.Id,EqualityComparer.Default); var group1_firstEmail = lookup[1].FirstOrDefault().Emails.FirstOrDefault() ; Assert.Equal("a1@163.com", group1_firstEmail); } [Fact] public void ToLookup_keySelector_elementSelector_Test() { var persons = new List() { new Employee(){ Id=1, Name="gaofeng",Emails=new List(){"a1@163.com","a2@163.com","a3@163.com"} }, new Employee(){ Id=1, Name="zhangsan",Emails=new List(){ "b1@163.com", "b2@163.com", "b3@163.com" } } }; var lookup = persons.ToLookup(q => q.Id, e=>e.Emails); var group1_Emails = lookup[1].FirstOrDefault(); var group1_Emails_first = group1_Emails.FirstOrDefault(); Assert.Equal("a1@163.com", group1_Emails_first); } [Fact] public void ToLookup_keySelector_elementSelector_comparer_Test() { var persons = new List() { new Employee(){ Id=1, Name="gaofeng",Emails=new List(){"a1@163.com","a2@163.com","a3@163.com"} }, new Employee(){ Id=1, Name="zhangsan",Emails=new List(){ "b1@163.com", "b2@163.com", "b3@163.com" } } }; var lookup = persons.ToLookup(q => q.Name, e => e.Emails,EqualityComparer.Default); var group1_Emails = lookup["gaofeng"].FirstOrDefault(); var group1_Emails_first = group1_Emails.FirstOrDefault(); Assert.Equal("a1@163.com", group1_Emails_first); } #endregion #region private private DataTable GetDataTable() { DataTable dt = new DataTable(); DataColumn col_id = new DataColumn("Id"); col_id.AllowDBNull = false; col_id.AutoIncrementSeed = 1; col_id.AutoIncrement = true; col_id.AutoIncrementStep = 1; col_id.DataType = typeof(int); DataColumn col_name = new DataColumn("Name"); col_name.AllowDBNull = true; col_name.AutoIncrement = false; col_name.DataType = typeof(string); col_name.DefaultValue = string.Empty; DataColumn col_age = new DataColumn("Age"); col_age.AllowDBNull = false; col_age.AutoIncrement = false; col_age.DataType = typeof(int); col_age.DefaultValue = 20; dt.Columns.Add(col_id); dt.Columns.Add(col_name); dt.Columns.Add(col_age); var row_one = dt.NewRow(); row_one[1] = "王高峰"; row_one[2] = 21; var row_2 = dt.NewRow(); row_2[1] = "王向前"; row_2[2] = 32; dt.Rows.Add(row_one); dt.Rows.Add(row_2); return dt; } private Students GetStudents() { Students arrStudent = new Students ( new Student[] { new Student() { Name = "张三", Age = 23 }, new Student() { Name = "李四", Age = 24 }, new Student() { Name = "王五", Age = 45 }, new Student() { Name = "DDD", Age = 21 }, new Student() { Name = "BBB", Age = 14 }, new Student() { Name = "CCC", Age = 3 }, new Student() { Name = "AAA", Age = 22 }, new Student() { Name = "BBB", Age = 55 }, new Student() { Name = "CCC", Age = 43 }, } ); return arrStudent; } #endregion } }