Why is my Navigation Properties empty in Entity Framework 4?
The code:
public ChatMessage[] GetAllMessages(int chatRoomId)
{
using (ChatModelContainer context = new ChatModelContainer(CS))
{
//var temp = context.ChatMessages.ToArray();
ChatRoom cr = context.ChatRooms.FirstOrDefault(c => c.Id == chatRoomId);
if (cr == null) return null;
return cr.ChatMessages.ToArray();
}
}
The problem:
The method (part of WCF-service) returns an empty array. If I uncomment the commented line it starts working as expected. I have tried turning of lazy loading but it didnt help.
Also, when it works, I get ChatMessages with a reference to ChatRoom populated but not the ChatParticipant. They are both referenced by the ChatMessage-entity in the schema with both Id and Navigation Properties. The Ids are set and points to the right entities but on the client-side only the ChatRoom-reference has been populated.
Related questions:
- Is an array the preferred method to return collections of EF-entities like this?
- When making a change in my model (edmx) Im required to run the "Generate Database from Model..."-option before I can run context.CreateDatabase(). Why? I get some error message pointing to old SSDL but I cant find where the SSDL is stored. Is this created when I run this "Generate Database..."-option?
- Is it safe to return entire entity-graphs to the client? Ive read some about "circular reference exeptions" but is thi开发者_开发问答s fixed in EF4?
- How and when is references populated in EF4? If I have lazy-loading turned on I suspect only entities I touch is populated? But with lazy loading turned off, should the entire graph be populated always then?
- Are there any drawbacks of using self-updating entities over ordinary entities in EF4? I dont need self-updating right now but I might do later. Can I upgrade easily or should I start with self-updating from the start?
- Why cant I use entity-keys with type string?
Each of your questions needs a separate answer, but I'll try to answer them as briefly as possible.
First of all, in the code sample you provided, you get a ChatRoom object and then try to access a related object that is not included in your query (ChatMessages). If lazy loading is turned off as you had suggested, then you will need the Include("ChatMessages") call in your query, so your LINQ query should look like this:
ChatRoom cr = context.ChatRooms.Include("ChatMessages").FirstOrDefault(c => c.Id == chatRoomId);
Please ensure that your connection string is in your config file as well.
For the related questions:
You can return collections in any way you choose - I have typically done them in a List object (and I think that's the common way), but you could use arrays if you want. To return as a list, use the .ToList() method call on your query.
I don't understand what you're trying to do here, are you using code to create your database from your EDMX file or something? I've typically used a database-first approach, so I create my tables etc then update my EDMX from the database. Even if you generate your DB from your model, you shouldn't have to run CreateDatabase in code, you should be able to run the generated script against your DB. If you are using code-only then you need to dump the EDMX file.
You can generally return entity graphs to the client, should handle ok.
EF4 should only populate what you need. If you use lazy loading, it will automatically load things that you do not include in your LINQ query when you reference them and execute the query (e.g. do a ToList() operation). This won't work so well if your client is across a physical boundary (eg a service boundary) obviously :) If you don't use lazy loading, it will load what you tell it to in your query and that is all.
Self tracking entities are used for n-tier apps, where objects have to be passed across physical boundaries (eg services). They come with an overhead of generated code for each object to keep track of its changes, they also generate POCO objects which are not dependent on EF4 (but obviously contain generated code that would make the tracked changes work with the EF4 tracker). I'd say it depends on your usage, if you're building a small app that's quite self contained, and don't really care about separation for testability without the infrastructure in place, then you don't need to use self tracking entities. I say only use framework features when you need them, so if you're not writing an enterprise scale application (enterprise doesn't have to be big, but something scalable, highly testable, high quality etc) then no need to go for self tracking POCOs.
I haven't tried but you should be able to do that - that would be a candidate for a separate question if you can't get it to work :)
精彩评论