views:

24

answers:

1

This one i had today is a strange one.

I have this query in an assembly method.

        public Order[] SelectAllOrders()
    {
        Order[] orders;
        using (MyDataContext context = new MyDataContext())
        {
            DataLoadOptions dlo = new DataLoadOptions();
            dlo.LoadWith<Order>(order => order.OrderDetails);
            context.LoadOptions = dlo;

            orders = context.Orders.Select(p => p).ToArray();
        }
        return orders;
    }

Supposed i already called the ToArray() the SQL Command executed and gave me the objects i need and i give them to a new Order[] array this should not need the DataContext instance. While im serializing the Order[] i get from the method return, serializer tries to access the DataContext again and i get an exception that cannot access disposed object.

Tried without the using() statement and works like it should. But, why i get this behavior? Anyone could give an explanation why deferred loading still remains while I'm calling .ToArray() and assigning new variable with the contents?

Thank you.

+1  A: 

The Select(p=>p) achieves very little; you might as well just call:

orders = context.Orders.ToArray();

Re the problem - I would guess that either OrderDetails hasn't really loaded, or it is trying to load some other data lazily. I would suggest investigating by (in a dev session):

    Order[] orders;
    using (MyDataContext context = new MyDataContext())
    {
        context.Log = Console.Out; // show me
        DataLoadOptions dlo = new DataLoadOptions();
        dlo.LoadWith<Order>(order => order.OrderDetails);
        context.LoadOptions = dlo;
        Console.WriteLine("> Calling ToArray");
        orders = context.Orders.ToArray();
        Console.WriteLine("> ToArray complete");

        // TODO: your extra code that causes serialziation, probably
        // involving `DataContractSerializer`

        Console.WriteLine("> Calling Dispose");
    }

With this, you should be able to see any extra database trips that are happning after the ToArray but before the Dispose(). The point being: this data is needed for serialization, so either a: ensure it gets loaded, or b: exclude it from serialization.

Marc Gravell
Marc, thanx for answering, i was not remembering how to show the SQL queries in the Output window to avoid the Console project test, couldn't find it yet :P. So, created the console and you're right and i was dumb forgot the association OrderDetails 1 - * Product. Answer is to LoadWith<OrderDetails>(od => od.Product) and its all good. Thank you....