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
{
///
/// 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);
}
///
/// 主要应用与Linq to sql
///
[Fact]
public void AsQueryable_Test()
{
//
}
///
/// 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());
}
///
/// 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();
});
}
///
/// 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);
}
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;
}
}
}