[EF]Include

1.Join(),两表不必含有外键关系,需要代码手动指定连接外键相等(具有可拓展性,除了值相等,还能指定是>,<以及其他对两表的相应键的关系),以及结果字段。

重载方式(是扩展方法,第一个参数带this,代表自身):

1.public static IQueryable<TResult> Join<TOuter, TInner, TKey, TResult>(this IQueryable<TOuter> outer, IEnumerable<TInner> inner, Expression<Func<TOuter, TKey>> outerKeySelector, Expression<Func<TInner, TKey>> innerKeySelector, Expression<Func<TOuter, TInner, TResult>> resultSelector);

2.public static IQueryable<TResult> Join<TOuter, TInner, TKey, TResult>(this IQueryable<TOuter> outer, IEnumerable<TInner> inner, Expression<Func<TOuter, TKey>> outerKeySelector, Expression<Func<TInner, TKey>> innerKeySelector, Expression<Func<TOuter, TInner, TResult>> resultSelector, IEqualityComparer<TKey> comparer);

2.Include(),两表必须含有外键关系,只需要指定键名对应的类属性名即可,不需指定结果字段(即全部映射)。默认搜索某表时,不会顺带查询外键表,直到真正使用时才会再读取数据库查询;若是使用 Include(),则会在读取本表时把指定的外键表信息也读出来。

/位于namespace System.Data.Entity.Infrastructure
public DbQuery<TResult> Include(string path);
//位于namespace System.Data.Entity,务必引入才能找到该方法。否则只看到上个方法
public static IQueryable<T> Include<T, TProperty>(this IQueryable<T> source, Expression<Func<T, TProperty>> path) where T : class;
        public static IQueryable<T> Include<T>(this IQueryable<T> source, string path) where T : class;

主从表结构设计中,如果我们直接以嵌套结构输出主表与从表数据。
每次外层的foreach循环每一次去取出订单时会执行单次的SQL查询,而内层foreach循环的每一笔明细同样会再执行一次查询,从而形成大量的数据库往返查询操作。可以采用EF提供的Incluede方法,将需要的数据一次性取出,避免频繁的查询操作。

            using (var context = new KTStoreModel()) {

                context.Database.Log = Console.Write;
                var customer = context.Customers.
                    Include("Orders.OrderDetails").
                    Include("Orders.OrderDetails.Product").
                    Where(c=>c.Id<5)  ;

                foreach(var c in customer)
                {
                    Console.WriteLine(c.ContactName);
                    foreach (var o in c.Orders)
                    {
                        Console.WriteLine("\tOrder_Id:{0}",o.Id);
                        foreach (var od in o.OrderDetails)
                        {
                            Console.WriteLine("\t\tProduct_Id:{0}\t{1}\tPrice:{2}",
                                od.ProductId, od.Product.Name, od.Price);
                        }
                    }
                }
                Console.WriteLine("done");

            }

调用Include会完整地载入关联数据,进一步的影响程序的执行运算,因此我们必须小心避免载入完整的关联数据,另外,也可以尝试通过异步的方式进行数据的加载操作,如此一来数据的加载操作就不会影响主程序的执行。

           await context.Orders.Include("Customer").ForEachAsync(o =>
                {
                    Console.WriteLine("{0}-{1}", o.Id, o.Customer.ContactName);
                    foreach (var od in o.OrderDetails)
                    {
                        Console.WriteLine("\t{0}", od.Product.Name);
                    }
                });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

厦门德仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值