Domanda

My model is simple

public partial class Customer
{
    public Customer()
    {
        this.Orders = new HashSet<Order>();
    }

    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Order> Orders { get; set; }
}

public partial class Order
{
    public Order()
    {
        this.OrderDetails = new HashSet<OrderDetail>();
    }

    public int Id { get; set; }
    public string OrderDescription { get; set; }
    public int CustomerId { get; set; }

    public virtual Customer Customer { get; set; }
    public virtual ICollection<OrderDetail> OrderDetails { get; set; }
}

public partial class OrderDetail
{
    public int Id { get; set; }
    public int OrderId { get; set; }
    public string ProductName { get; set; }
}

This code was generated using EF's .edmx file. Then I generated my database from this model. I am doing eager loading to fetch data.

    public virtual IQueryable<T> GetAllEagerLoadSelective(string[] children)
    {
        foreach (var item in children)
        {
            DbSet.Include(item).Load();
        }
        return DbSet;
    } 

and my call looks like

        string[] Navs = { "OrderDetails" };
        var orders = VNUow.Order.GetAllEagerLoadSelective(Navs);
        var temp = orders.ToList();
        return temp;

LazyLoading is set to false .

There are two queries being run, The first one makes sense

SELECT 
[Project1].[Id] AS [Id], 
[Project1].[OrderDescription] AS [OrderDescription], 
[Project1].[CustomerId] AS [CustomerId], 
[Project1].[C1] AS [C1], 
[Project1].[Id1] AS [Id1], 
[Project1].[OrderId] AS [OrderId], 
[Project1].[ProductName] AS [ProductName]
FROM ( SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[OrderDescription] AS [OrderDescription], 
    [Extent1].[CustomerId] AS [CustomerId], 
    [Extent2].[Id] AS [Id1], 
    [Extent2].[OrderId] AS [OrderId], 
    [Extent2].[ProductName] AS [ProductName], 
    CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
    FROM  [dbo].[Orders] AS [Extent1]
    LEFT OUTER JOIN [dbo].[OrderDetails] AS [Extent2] ON [Extent1].[Id] = [Extent2].[OrderId]
)  AS [Project1]
ORDER BY [Project1].[Id] ASC, [Project1].[C1] ASC

but why is there this second query? A select on the parent table...

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[OrderDescription] AS [OrderDescription], 
[Extent1].[CustomerId] AS [CustomerId]
FROM [dbo].[Orders] AS [Extent1]
È stato utile?

Soluzione

You are calling Load() to populate the internal sets, which is what creates the first query. Then you're returning the dbSet. Then you call ToList() on the DbSet which is effectively another query entirely. The only time querying a DbSet does not result in a database query is when you use the Find() function to retrieve an entity that has already been loaded. Everything else is a query to the db even if it is only returning entities that have already been loaded.

To fix this, change GetAllEagerLoadSelective like so:

public virtual IList<T> GetAllEagerLoadSelective(string[] children)
{
    IQueryable<T> dbSet = DbSet;
    foreach (var item in children)
    {
        dbSet = dbSet.Include(item);
    }
    return dbSet.ToList();
} 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top