With Linq to SQL lazy loading is used by default. That means that if one object contains another object, the child object will only be loaded when first accessing it. Using Load Options it is possible to tell Linq to SQL to also load the child object at the same time as loading it’s parent.
Using the structure explained in my posts Base Repository/Business Logic wrapper and ObjectDataSource binding withing paging and sorting I am able to easily display a GridView showing the following:
For title I’d like to show the title name instead of just the ID. Title is a lookup table and Linq to SQL has created the following relationship:
For this reason I should be to change my markup to use Title.Name in the binding:
<asp:TemplateField HeaderText="Title" SortExpression="TitleID"> <ItemTemplate> <asp:Literal Text='<%# Eval("Title.Name") %>' runat="server" /> </ItemTemplate> <EditItemTemplate> <asp:DropDownList ID="ddlEditTitle" DataSourceID="odsTitle" DataValueField="ID" DataTextField="Name" SelectedValue='<%# Bind("TitleID") %>' runat="server" /> </EditItemTemplate> </asp:TemplateField>
Due to my repository objects automatically closing the DataContext on disposal and Linq to SQL using lazy loading by default, when the binding calls Title.Name it attempts to query the database and the following error is shown:
Cannot access a disposed object.
Object name: ‘DataContext accessed after Dispose.’
What I can do here is use Load Options to tell Linq to SQL to load the Title data at the same time as retrieving Student data. Using my repository model I can put the following code in the constructor of the StudentRepository:
DataLoadOptions options = new DataLoadOptions(); options.LoadWith<Student>(s => s.Title); Context.LoadOptions = options;
My grid now shows the title name instead of the ID, but still uses the ID in edit mode to select the correct item in the DropDownList: