在方法中处理 DataContext 的最佳 LINQ-to-SQL 策略是什么?

发布于 2024-08-10 07:52:40 字数 1993 浏览 2 评论 0原文

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

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

我可以取出我的 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;
}

I understand that it is good practice to use a using block when getting data from the LINQ-to-SQL classes as shown below.

However, when I do this, I can only access the shallow properties of orders (e.g. Order.OrderId) but not the deeper properties (e.g. Customer.CustomerName) since they seem to be disposed of at this point.

I can take out my using block which allows me to access Customers, but this does not free the resources.

What is the best practice here?

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;
            }
        }

    }
}

Answer:

Thanks Adam, using your suggestion I got my code to work like this:

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不乱于心 2024-08-17 07:52:40

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

一般来说,您的 DataContext 应在您的工作单元的持续时间内有效,因此此处显示您的 DataContext 需要在这个方法并传入(或者甚至声明为 DataContext 上的扩展方法)。

这是关于 DataContext博客文章 > 生命周期管理。

The deeper properties of the object can't be accessed because LINQ-to-SQL uses lazy loading (that is, it automatically retrieves those records as needed, so when you access them for the first time it performs a database operation). Because the DataContext is disposed, it can't perform the necessary database operations. It is possible to have properties like this loaded "eagerly" (meaning at the time of initial retrieval), but you'll have to know all of these up front.

In general, your DataContext should live for the duration of your unit of work, so it appears here that your DataContext needs to be declared outside of this method and passed in (or even declared as an extension method on your DataContext).

Here is a good blog post on DataContext lifetime management.

你对谁都笑 2024-08-17 07:52:40

如果您知道您想要获取客户,则可以在 DataLoadOptions 中指定这一点,它将连接请求以急切地加载它们,而不是延迟加载它们。

这是有关 DataLoadOptions 的 msdn 文章

例子:

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

If you know for a fact that you're going to want to get Customers, you can specify that in the DataLoadOptions and it will wire up the request to eagerly load them instead of lazily loading them.

Here's the msdn article on DataLoadOptions.

Example:

var dlo = new DataLoadOptions();
dlo.LoadWith<Order>(o => o.Customer); 
context.DataLoadOptions = dlo;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文