Linq延迟加载

IEnumerable在foreach和ToArrary之类的会立即执行。

实体类:LocalData本地数据,不含创建人时间信息;DBData含创建时间信息

1、select延迟

 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; }
    }
View Code
  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,
            });
View Code

虽然在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延迟

 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);
        }
View Code

A=list是延迟加载,含有三个对象的数组;B=foreach(list),只有两个对象的数组;C=ToArray(list),也只有两个对象的数组。B=C。

原因:B和C都指向A的地址

 

posted @ 2016-05-26 13:42  江境纣州  阅读(33)  评论(0编辑  收藏  举报