Linq2SQl eager load with multiple DataLoadOptions

2020-02-09 03:36发布

问题:

I like to fetch the data with eager-loading using Linq2SQL. The code is similar as :

       DataLoadOptions options = new DataLoadOptions();

       options.LoadWith<Product>(c => c.ProductCompanies);

       options.LoadWith<Product>(c => c.OrderDetails);

       db.LoadOptions = options;

       IEnumerable<Product> products = db.Products.ToList<Product>();

I check it generated more than 1 SQL query as I expected. Actually it only do eager-loading with Product and OrderDetails, and the ProductCompany is queried one by one. Did I do anything wrong here? Or it is a Linq2SQL issue? Do we have any workaround?

Thanks a lot!

Update: I check the sql from SQL Profiler. I found both Leppie and Ian are correct. They are bounded in one transaction. But when I set it as lazy load, it opened multiple connection.

回答1:

No, you didn't do anything wrong, Linq2SQL batches everything in a single transaction, but might execute an unbounded number of queries for the required result. DataLoadOptions is normally only used when the DataContext is not available for the entire context of the resulting usage. If you can keep the DataContext alive during execution, it is best to rely on deferred execution (that is default).



回答2:

I hit this issue in some code too, and after much experimenting and googling it looks like LINQ can only join across a single one-to-many relationship from each table : if you try to specify more than one to pre-load it just (randomly?) picks which one to pre-load and which others to leave deferred (simply ignoring those LoadWith hints)

Other people have posted this too, for example

http://codebetter.com/blogs/david.hayden/archive/2007/08/06/linq-to-sql-query-tuning-appears-to-break-down-in-more-advanced-scenarios.aspx



回答3:

According to the docs:

When you query for an object, you actually retrieve only the object you requested. The related objects are not automatically fetched at the same time.

The DataLoadOptions class provides two methods to achieve immediate loading of specified related data. The LoadWith method allows for immediate loading of data related to the main target. The AssociateWith method allows for filtering related objects.

Having multiple sql statements doesn't surprise me. I think the difference here is all statements are just loaded up front instead of lazy loading them on demand.