This is a migrated thread and some comments may be shown as answers.

[Solved] Need Help w/ Lazy Loading and Foreign Keys

4 Answers 185 Views
GridView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Joshua
Top achievements
Rank 1
Joshua asked on 22 May 2011, 04:06 AM
Attached is a cropped version of my Entity Data Model.  You'll see that the main table (for this particular case) is the "Check".  I have two "foreign" tables, "Consumer" and "VeterinaryClinic".  Each of those two tables both reference the "Contact" table.  My objective is to have a GridView show certain linked columns from all four tables for each "Check" record on one row (no gridview hierarchies). AND, I don't want to perform a database call on each row bound event.

I assumed I could use the LINQ ".Include" statements to load information from the two foreign tables. But, if you look at my XAML below, the GridViewDataColumn property DataMemberBinding="{Binding Consumer.ContactId}" doesn't return anything.  How do I accomplish this?  Does lazy loading affect this (btw, I've tried it with lazy loading enabled and disabled to no avail)? Also, how do I accomplish the addition of the referenced "Contact" for each row?

I guess I could always create a custom function in the Domain Service that returns an object that only performs the joins once on server-side and then returns that full list.  However, I would think there's a more efficient way?

My DomainService call:
public IQueryable<Check> GetChecks()
{
    return this.ObjectContext.Checks
                     .Include("Consumer")
                     .Include("VeterinaryClinic");
}

My Xaml:
<riaControls:DomainDataSource AutoLoad="True" Height="0" Width="0" Name="checksDataSource" QueryName="GetChecks">
    <riaControls:DomainDataSource.DomainContext>
        <bbmbiz:BBMBizDomainContext />
    </riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>
<telerik:RadGridView Name="rgvChecks" HorizontalAlignment="Left"
                     VerticalAlignment="Top" ShowGroupPanel="False"
                     RowIndicatorVisibility="Collapsed"
                     CanUserDeleteRows="False"
                     ShowInsertRow="False"
                     CanUserReorderColumns="False"
                     CanUserResizeColumns="True"
                     AutoGenerateColumns="False"
                     CanUserFreezeColumns="True"
                     ItemsSource="{Binding ElementName=checksDataSource, Path=Data}"
                     IsBusy="{Binding IsBusy, ElementName=checksDataSource}" Width="800"
                     RowEditEnded="rgvChecks_RowEditEnded">
    <telerik:RadGridView.Columns>
        <telerik:GridViewDataColumn DataMemberBinding="{Binding ConsumerId}" Header="Consumer ID" UniqueName="ConsumerID" />
        <telerik:GridViewDataColumn DataMemberBinding="{Binding Consumer.ContactId}" Header="Contact ID" UniqueName="ContactID" />
    </telerik:RadGridView.Columns>
</telerik:RadGridView>


Thanks,
Joshua

4 Answers, 1 is accepted

Sort by
0
Joshua
Top achievements
Rank 1
answered on 22 May 2011, 05:51 AM
Update:

After adding a breakpoint, I have confirmed that the DomainService was not originally loading the Navigation Properties because of lazy loading. So here's the updated DomainService query which I have confirmed by looking at the result set from the breakpoint that all data is loaded.  By disabling LazyLoading and issuing "LoadProperty" on one property (i.e. "Consumer" in this case), I'm explicitly forcing the loading of all three navigation properties.

I also figured out how to load the associated "Contact" navigation property.

BUT, the GridView is still not displaying navigational data. PLEASE HELP.

DomainService:
public IQueryable<Check> GetChecks()
{
    this.ObjectContext.ContextOptions.LazyLoadingEnabled = false;
    var returnSet = this.ObjectContext.Checks
                            .Include("Consumer")
                            .Include("VeterinaryClinic")
                            .Include("Consumer.Contact");
    foreach (Check check in returnSet)
        this.ObjectContext.LoadProperty(check, "Consumer");
    return returnSet;
}

XAML (same as above except):
<telerik:GridViewDataColumn DataMemberBinding="{Binding Consumer.Contact.FirstName}" Header="First Name" UniqueName="FirstName" />

Thanks,
Joshua

0
Joshua
Top achievements
Rank 1
answered on 22 May 2011, 06:33 AM
Okay, another piece of info...

at the line:
return returnSet;

I have confirmed that the returnSet contains the additonal navigational property data.  However, just to test what's being loaded, I created an explicit exception in
private void checksDataSource_LoadedData(object sender, LoadedDataEventArgs e)
{
    Check check = e.Entities.First() as Check;
    throw new System.Exception(check.Consumer.ContactId.ToString());
}

This returns "Object reference not set to an instance of an object".  So, why is the navigational properties being lost after the information is returned to the DomainDataSource?

Thanks,
Joshua
0
Joshua
Top achievements
Rank 1
answered on 23 May 2011, 04:15 AM
I got it.  I wasn't adding the "Include" attribute to the metadata.  Everything's working now.
0
Lorenz Buchberger
Top achievements
Rank 1
answered on 26 Jul 2011, 09:58 PM
Hi Joshua,

I_m facing the same prob but didn't understand what you mean:
I have a generated EF Model und add the Include in my GetTable function: Where do I have to add the Include statement as well ?

kind regards

Lorenz
Tags
GridView
Asked by
Joshua
Top achievements
Rank 1
Answers by
Joshua
Top achievements
Rank 1
Lorenz Buchberger
Top achievements
Rank 1
Share this question
or