Reputation: 1677
I have a database schema (MySql) exposed as a data/OData service that is queried by my Silverlight client using Linq. Here is the model in question:
The columns Level and Application are Int values referencing via a foreign key the tables lookuplevel and lookuppid respectively.
So, an entry in the logstest table may look like this:
ID:35
Date: 2012-02-29
Level: 1
Application: 1
Message: MyMessage
Exception: MyException
ReverseOrder: 56 (don't mind this column)
And we could have in lookuplevel:
ID: 1
String: Warning
And in lookuppid
ID: 1
String: Product A
As you can see, the Level and Application columns are actually mapped to a value in there referenced table.
Now client side (Silverlight), I get the content of the logstest table via a linq query.
public void LoadErrors()
{
var linqQuery = (from e in _myEntities.logstests
select e);
AsyncCallback GetDataComplete = new AsyncCallback(MyCallback);
((DataServiceQuery<logstest>)linqQuery).BeginExecute(GetDataComplete, linqQuery);
}
private void MyCallback(IAsyncResult asyncResult)
{
DataServiceQuery<logstest> query = asyncResult.AsyncState as DataServiceQuery<logstest>;
foreach (logstest error in e.Query.EndExecute(e.Result))
{
Error newError = new Error
{
Date = error.Date,
Level = error.lookuplevel.String,
Application = error.lookuppid.String,
Message = error.Message,
Exception = error.Exception
};
}
// Do more stuff...
}
Error is a custom class that is binded on a datagrid that displays each field in a separate column.
Obviously, for the columns Level and Application, I do not want to display the index of the value they reference but the value itself (ie: for Level I want to display Warning and not 1).
The problem is that both error.lookuplevel and error.lookuppid are null and I have no idea why. Is there a gotcha somewhere that I don't know about?
Thanks in advance!
Upvotes: 2
Views: 3119
Reputation: 13320
You must explicitely ask to include the related entity, otherwise WCF DS Client will not ask for it on the server. And it also doesn't do lazy loading of the navigation properties, since the lazy load would have to invoke an HTTP request which can take a really long time, and so it's not a good idea to do that inside a property getter.
To ask to include related entities, you need to add $expand to the query, like this:
var linqQuery = (from e in
_myEntities.logstests.Expand("lookuppid").Expand("lookuplevel")
select e);
Upvotes: 4
Reputation: 13381
Please install EF 4.1 from http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=8363 to stop using magic strings inside Include. Add
using System.Data.Entity;
to your using statements.
Then write the following query:
var linqQuery = _myEntities.logstests.Include(e=>e.lookuppid).Include(e=>e.lookuplevel);
For more information refer to the following http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx
Upvotes: 0
Reputation: 16651
Normally in EF if you don't have lazy loading enabled in the context you need to include the navigation property by name in the query:
var linqQuery = (from e in
_myEntities.logstests.Include("lookuppid").Include("lookuplevel")
select e);
Upvotes: 0