【问题标题】:What is the best LINQ-to-SQL strategy for disposing of DataContext within methods?在方法中处理 DataContext 的最佳 LINQ-to-SQL 策略是什么?
【发布时间】:2009-11-05 13:39:12
【问题描述】:

我了解在从 LINQ-to-SQL 类获取数据时使用using 块是一种很好的做法,如下所示。

但是,当我这样做时,我只能访问orders 的浅层属性(例如Order.OrderId),而不能访问更深层的属性(例如Customer.CustomerName),因为此时它们似乎已被处理掉。

我可以取出允许我访问客户的 using 块,但这不会释放资源。

这里的最佳做法是什么?

using System;
using System.Collections.Generic;
using System.Linq;
using TestExtn2343.Models;

namespace TestExtn2343
{
    class Program
    {
        public static void Main(string[] args)
        {

            var orders = GetOrders(10, 10);

            orders.ForEach(x =>
            {
                Customer customer = x.Customer;
                if (customer != null)
                {
                    //SUCCEEDS:
                    Console.WriteLine("{0}, {1}", x.OrderID);

                    //FAILS: "
                    Console.WriteLine("{0}, {1}", x.OrderID, x.Customer.ContactName.ToString());
                }
            });

            Console.ReadLine();
        }

        public static List<Order> GetOrders(int skip, int take)
        {
            using (MainDataContext db = new MainDataContext())
            {
                List<Order> orders = (from order in db.Orders
                                      select order).Skip(skip).Take(take).ToList();
                return orders;
            }
        }

    }
}

答案:

感谢 Adam,根据您的建议,我的代码可以像这样工作:

public static void Main(string[] args)
{
    using (MainDataContext db = new MainDataContext())
    {
        GetOrders(db, 10, 10).ForEach(x => Console.WriteLine("{0}, {1}", x.OrderID, x.Customer.ContactName.ToString()));
    }
    Console.ReadLine();
}

public static List<Order> GetOrders(MainDataContext db, int skip, int take)
{
    List<Order> orders = (from order in db.Orders
                          select order).Skip(skip).Take(take).ToList();
    return orders;
}

【问题讨论】:

    标签: c# linq-to-sql datacontext


    【解决方案1】:

    无法访问对象的更深层属性,因为 LINQ-to-SQL 使用 延迟加载(也就是说,它会根据需要自动检索这些记录,因此当您第一次访问它们时它执行数据库操作的时间)。因为DataContext 被释放了,所以它不能执行必要的数据库操作。可以“急切地”加载此类属性(即在初始检索时),但您必须事先了解所有这些。

    一般来说,您的DataContext 应该在您的工作单元期间存在,因此这里看来您的DataContext 需要在此方法之外声明并传入(或甚至在您的DataContext 上声明为扩展方法。

    这是一个很好的blog post DataContext 生命周期管理。

    【讨论】:

      【解决方案2】:

      如果您知道您想要获得客户,您可以在 DataLoadOptions 中指定它,它会连接请求以急切地加载它们,而不是懒惰地加载它们。

      这是msdn article on DataLoadOptions

      例子:

      var dlo = new DataLoadOptions();
      dlo.LoadWith<Order>(o => o.Customer); 
      context.DataLoadOptions = dlo;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-13
        • 1970-01-01
        • 2010-10-23
        • 2010-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多