Linq延迟加载
IEnumerable在foreach和ToArrary之类的会立即执行。
实体类:LocalData本地数据,不含创建人时间信息;DBData含创建时间信息
1、select延迟
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class BaseEntity { public Guid ID { get; set; } } public class BaseCreateUpdateLogEntity : BaseEntity { /// <summary> /// 创建人相关ID /// </summary> public Guid? CreateBy { get; set; } /// <summary> /// 创建相关时间 /// </summary> public DateTime CreateOn { get; set; } /// <summary> /// 更新人相关ID /// </summary> public Guid? UpdateBy { get; set; } /// <summary> /// 更新相关时间 /// </summary> public DateTime UpdateOn { get; set; } } public class DBData : BaseCreateUpdateLogEntity { /// <summary> /// 员工ID /// </summary> public Guid MonthlyEmployeeID { get; set; } /// <summary> /// 15位证件号 /// </summary> public string Credential15 { get; set; } /// <summary> /// 参保月 /// </summary> public DateTime InsuranceDate { get; set; } /// <summary> /// 服务费 /// </summary> public decimal ServiceCharge { get; set; } } public class LocalData { public Guid ID { get; set; } public string Credential { get; set; } public DateTime Date { get; set; } public decimal Charge { get; set; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var list = new List<LocalData>(); list.Add(new LocalData { ID = Guid.NewGuid(), Credential = "11", Date = DateTime.Now, Charge = 11M, }); list.Add(new LocalData { ID = Guid.NewGuid(), Credential = "22", Date = DateTime.Now, Charge = 22M, }); list.Add(new LocalData { ID = Guid.NewGuid(), Credential = "33", Date = DateTime.Now, Charge = 33M, });
虽然在foreach中给list设置了创建时间人的信息,但是在在list.ToArrary()中并没有创建时间人的信息。
原因一:原因是延迟加载,相当于A=list(延迟加载),B=foreach(list)(立即加载),C=ToArrary(list)(立即加载),所以B!=C。
原因二:DBData是LocalData+Select(Action)的延迟加载,但是DBData和LocalData是两个不同的类型,相当于协变,导致DBData指向IEnumerable接口,
所以原因一种的A指向的是LocalData对象,而B指向的是DBData对象,地址不一样,导致B循环中即使为CreateBy赋了值,在C中仍然是空的。
2、where延迟
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void Main(string[] args) { var list = new List<DBData>(); list.Add(new DBData { ID = Guid.NewGuid(), Credential15 = "11", InsuranceDate = DateTime.Now, ServiceCharge = 11M, }); list.Add(new DBData { ID = Guid.NewGuid(), Credential15 = "22", InsuranceDate = DateTime.Now, ServiceCharge = 22M, }); list.Add(new DBData { ID = Guid.NewGuid(), Credential15 = "33", InsuranceDate = DateTime.Now, ServiceCharge = 33M, }); var ls = list.Where(p => p.ServiceCharge > 20); WriteToServer(ls, Guid.NewGuid()); Console.Read(); } public static void WriteToServer<T>(IEnumerable<T> list, Guid createBy) where T : BaseCreateUpdateLogEntity { if (list == null || list.Count() == 0) return; foreach (var item in list) { item.ID = Guid.NewGuid(); item.CreateBy = createBy; item.CreateOn = DateTime.Now; item.UpdateBy = createBy; item.UpdateOn = DateTime.Now; } Console.WriteLine(list.ToArray()[0].CreateBy); }
A=list是延迟加载,含有三个对象的数组;B=foreach(list),只有两个对象的数组;C=ToArray(list),也只有两个对象的数组。B=C。
原因:B和C都指向A的地址