Entity Framework explicitly included navigation property is null - c#

I've got lazy loading off, and proxy creation doesn't matter (tried both true and false, no difference).
I have this model:
public class Comment{
[Required]
public int SenderID { get; set; }
public User Sender { get; set; }
}
(and of course, I have a user class).
At database level, I confirm that the Sender is a valid User object. I have some IQueryable<Comment> named commentsQuery (that basically takes some comments from a post. Then I include the Sender navigation property and execute the query:
var comments = commentsQuery.Take(50).OrderBy(c => c.ID).Include(c => c.Sender).ToList();
However, some comment objects inside the list have their Sender set to null even though I've explicitly included the navigation property.
If I turn on lazy loading it works correctly, but I don't want to turn on lazy loading.
Why is the explicitly-included required navigation property null? (I'm on Entity Framework 6.1.3)

Okay, just figured out myself. I had to include the sender at the original query when I'm constructing it from the database context.
I was using:
var post = await Database.Posts.Where(p => p.ID == postId && p.Sender.Username == username).Include(p => p.Sender).Include(p => p.Comments).FirstOrDefaultAsync();
IQueryable<Comment> commentsQuery = post.Comments.ActiveObjects().OrderByDescending(c => c.ID).AsQueryable();
And then, I assume Entity Framework was just ignoring (I think it's a design issue at Microsoft's side) the later-included navigation property (commentsQuery.[...].Include(c => c.Sender)).
I've modified the original query to include the second-level navigation property:
var post = await Database.Posts.Where(p => p.ID == postId && p.Sender.Username == username).Include(p => p.Sender).Include(p => p.Comments).Include(p => p.Comments.Select(c => c.Sender)).FirstOrDefaultAsync();
(notice the addition of .Include(p => p.Comments.Select(c => c.Sender))
Now, my query works properly. I'm not sure if it's the best way to do it though, anyway, it's not the scope of this question.

Related

EF Core not tracking the correct property in a unit of work scenario

This question is an abstract of the problem that I am facing: consider the below,
I have entities with the following properties
public class Entity
{
public int Id { get; set; }
public int Status { get; set; }
}
Status can be 0 (New) or 1 (Deleted).
I have a service call which alters the entity from 0 -> 1 which is called through the service. The repository involved does not call context.SaveChanges(), instead this is handled farther up the chain in middleware.
This looks like:
var entity = await Context.Entities.FirstOrDefaultAsync(x => x.Id == id);
entity.SetDeleted();
Where the SetDeleted method changes the property from 0 to 1.
Then, in another service method (in the same unit of work) this is read to check if there is an entity which isn't deleted. This is where the problem occurs.
The code looks like:
var entities = context.Entities.Any(x => x.Status != 1);
Usually you would expect the graph to not be returned, but unfortunately it is. Strangely enough when you execute the ToList() function and then run the same operation it doesn't include the graph. This means that if you have the below:
var entities = await Context.Entities.Where(x => x.Status!= 1).ToListAsync();
var secondFilter = entities.Where(x => x.Status != 1).ToList();
The entities will contain the entity, the secondFilter will not contain the entity despite it being subject to the same rules.
Has anyone had this problem, does anyone know a solution?
This is by-design behavior of EF.
When you have a tracked entity, and query the same entity from the database, the tracked entity is never overwritten.
After
var entity = await Context.Entities.FirstOrDefaultAsync(x => x.Id == id);
entity.SetDeleted();
You have one tracked entity, with a modified Status.
This
var entities = await Context.Entities.Where(x => x.Status!= 1).ToListAsync();
Runs a SQL query and finds the same entity as its Status=0 in the database. But when when EF tries to add the entity to the change tracker it discovers that there's a modified version already there, and so it discards the data read from the database and adds the existing modified entity to the entities collection. Then this
var secondFilter = entities.Where(x => x.Status != 1).ToList();
returns nothing because entity has Status=1.

Using Include with Intersect/Union/Exclude in Linq

What seemed that it should be a relatively straight-forward task has turned into something of a surprisingly complex issue. To the point that I'm starting to think that my methodology perhaps is simply out of scope with the capabilities of Linq.
What I'm trying to do is piece-together a Linq query and then invoke .Include() in order to pull-in values from a number of child entities. For example, let's say I have these entities:
public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public ISet<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public Parent Parent { get; set; }
public string Name { get; set; }
}
And let's say I want to perform a query to retrieve records from Parent, where Name is some value and Location is some other value, and then include Child records, too. But for whatever reason I don't know the query values for Name and Location at the same time, so I have to take two separate queryables and join them, such:
MyDbContext C = new MyDbContext();
var queryOne = C.Parent.Where(p => p.Name == myName);
var queryTwo = C.Parent.Where(p => p.Location == myLocation);
var finalQuery = queryOne.Intersect(queryTwo);
That works fine, producing results exactly as if I had just done:
var query = C.Parent.Where(p => p.Name == myName && p.Location = myLocation);
And similarly, I can:
var finalQuery = queryOne.Union(queryTwo);
To give me results just as if I had:
var query = C.Parent.Where(p => p.Name == myName || p.Location = myLocation);
What I cannot do, however, once the Intersect() or Union() is applied, however, is then go about mapping the Child using Include(), as in:
finalQuery.Include(p => p.Children);
This code will compile, but produces results as follows:
In the case of a Union(), a result set will be produced, but no Child entities will be enumerated.
In the case of an Intersect(), a run-time error is generated upon attempt to apply Include(), as follows:
Expression of type
'System.Collections.Generic.IEnumerable`1[Microsoft.EntityFrameworkCore.Query.Internal.AnonymousObject]'
cannot be used for parameter of type
'System.Collections.Generic.IEnumerable`1[System.Object]' of method
'System.Collections.Generic.IEnumerable`1[System.Object]
Intersect[Object](System.Collections.Generic.IEnumerable`1[System.Object],
System.Collections.Generic.IEnumerable`1[System.Object])'
The thing that baffles me is that this code will work exactly as expected:
var query = C.Parent.Where(p => p.Name == myName).Where(p => p.Location == myLocation);
query.Include(p => p.Children);
I.e., with the results as desired, including the Child entities enumerated.
my methodology perhaps is simply out of scope with the capabilities of Linq
The problem is not LINQ, but EF Core query translation, and specifically the lack of Intersect / Union / Concat / Except method SQL translation, tracked by #6812 Query: Translate IQueryable.Concat/Union/Intersect/Except/etc. to server.
Shortly, such queries currently use client evaluation, which with combination of how the EF Core handles Include leads to many unexpected runtime exceptions (like your case #2) or wrong behaviors (like Ignored Includes in your case #1).
So while your approach technically perfectly makes sense, according to the EF Core team leader response
Changing this to producing a single SQL query on the server isn't currently a top priority
so this currently is not even planned for 3.0 release, although there are plans to change (rewrite) the whole query translation pipeline, which might allow implementing that as well.
For now, you have no options. You may try processing the query expression trees yourself, but that's a complicated task and you'll probably find why it is not implemented yet :) If you can convert your queries to the equivalent single query with combined Where condition, then applying Include will be fine.
P.S. Note that even now your approach technically "works" w/o Include, prefomance wise the way it is evaluated client side makes it absolutely non equivalent of the corresponding single query.
A long time has gone by, but this .Include problem still exists in EF 6. However, there is a workaround: Append every child request with .Include before intersecting/Unionizing.
MyDbContext C = new MyDbContext();
var queryOne = db.Parents.Where(p => p.Name == parent.Name).Include("Children");
var queryTwo = db.Parents.Where(p => p.Location == parent.Location).Include("Children");
var finalQuery = queryOne.Intersect(queryTwo);
As stated by #Ivan Stoev, Intersection/Union is done with after-fetched data, while .Include is ok at request time.
So, as of now, you have this one option available.

Entity Framework Include directive not getting all expected related rows

While debugging some performance issues I discovered that Entity framework was loading a lot of records via lazy loading (900 extra query calls ain't fast!) but I was sure I had the correct include. I've managed to get this down to quite a small test case to demonstrate the confusion I'm having, the actual use case is more complex so I don't have a lot of scope to re-work the signature of what I'm doing but hopefully this is a clear example of the issue I'm having.
Documents have Many MetaInfo rows related. I want to get all documents grouped by MetaInfo rows with a specific value, but I want all the MetaInfo rows included so I don't have to fire off a new request for all the Documents MetaInfo.
So I've got the following Query.
ctx.Configuration.LazyLoadingEnabled = false;
var DocsByCreator = ctx.Documents
.Include(d => d.MetaInfo) // Load all the metaInfo for each object
.SelectMany(d => d.MetaInfo.Where(m => m.Name == "Author") // For each Author
.Select(m => new { Doc = d, Creator = m })) // Create an object with the Author and the Document they authored.
.ToList(); // Actualize the collection
I expected this to have all the Document / Author pairs, and have all the Document MetatInfo property filled.
That's not what happens, I get the Document objects, and the Authors just fine, but the Documents MetaInfo property ONLY has MetaInfo objects with Name == "Author"
If I move the where clause out of the select many it does the same, unless I move it to after the actualisation (which while here might not be a big deal, it is in the real application as it means we're getting a huge amount more data than we want to deal with.)
After playing with a bunch of different ways to do this I think it really looks like the issue is when you do a select(...new...) as well as the where and the include. Doing the select, or the Where clause after actualisation makes the data appear the way I expected it to.
I figured it was an issue with the MetaInfo property of Document being filtered, so I rewrote it as follows to test the theory and was surprised for find that this also gives the same (I think wrong) result.
ctx.Configuration.LazyLoadingEnabled = false;
var DocsByCreator = ctx.Meta
.Where(m => m.Name == "Author")
.Include(m => m.Document.MetaInfo) // Load all the metaInfo for Document
.Select(m => new { Doc = m.Document, Creator = m })
.ToList(); // Actualize the collection
Since we're not putting the where on the Document.MetaInfo property I expected this to bypass the problem, but strangely it doesn't the documents still only appear to have "Author" MetaInfo object.
I've created a simple test project and uploaded it to github with a bunch of test cases in, as far as I can tell they should all pass, bug only the ones with premature actualisation pass.
https://github.com/Robert-Laverick/EFIncludeIssue
Anyone got any theories? Am I abusing EF / SQL in some way I'm missing? Is there anything I can do differently to get the same organisation of results? Is this a bug in EF that's just been hidden from view by the LazyLoad being on by default, and it being a bit of an odd group type operation?
This is a limitation in EF in that Includes will be ignored if the scope of the entities returned is changed from where the include was introduced.
I couldn't find the reference to this for EF6, but it is documented for EF Core. (https://learn.microsoft.com/en-us/ef/core/querying/related-data) (see "ignore includes") I suspect it is a limit in place to stop EF's SQL generation from going completely AWOL in certain scenarios.
So while var docs = context.Documents.Include(d => d.Metas) would return the metas eager loaded against the document; As soon as you .SelectMany() you are changing what EF is supposed to return, so the Include statement is ignored.
If you want to return all documents, and include a property that is their author:
var DocsByCreator = ctx.Documents
.Include(d => d.MetaInfo)
.ToList() // Materialize the documents and their Metas.
.SelectMany(d => d.MetaInfo.Where(m => m.Name == "Author") // For each Author
.Select(m => new { Doc = d, Creator = m })) // Create an object with the Author and the Document they authored.
.ToList(); // grab your collection of Doc and Author.
If you only want documents that have authors:
var DocsByCreator = ctx.Documents
.Include(d => d.MetaInfo)
.Where(d => d.MetaInfo.Any(m => m.Name == "Author")
.ToList() // Materialize the documents and their Metas.
.SelectMany(d => d.MetaInfo.Where(m => m.Name == "Author") // For each Author
.Select(m => new { Doc = d, Creator = m })) // Create an object with the Author and the Document they authored.
.ToList(); // grab your collection of Doc and Author.
This means you will want to be sure that all of your filtering logic is done above that first 'ToList() call. Alternatively you can consider resolving the Author meta after the query such as when view models are populated, or an unmapped "Author" property on Document that resolves it. Though I generally avoid unmapped properties because if their use slips into an EF query, you get a nasty error at runtime.
Edit: Based on the requirement to skip & take I would recommend utilizing view models to return data rather than returning entities. Using a view model you can instruct EF to return just the raw data you need, compose the view models with either simple filler code or utilizing Automapper which plays nicely with IQueryable and EF and can handle most deferred cases like this.
For example:
public class DocumentViewModel
{
public int DocumentId { get; set; }
public string Name { get; set; }
public ICollection<MetaViewModel> Metas { get; set; } = new List<MetaViewModel>();
[NotMapped]
public string Author // This could be update to be a Meta, or specialized view model.
{
get { return Metas.SingleOrDefault(x => x.Name == "Author")?.Value; }
}
}
public class MetaViewModel
{
public int MetaId { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
Then the query:
var viewModels = context.Documents
.Select(x => new DocumentViewModel
{
DocumentId = x.DocumentId,
Name = x.Name,
Metas = x.Metas.Select(m => new MetaViewModel
{
MetaId = m.MetaId,
Name = m.Name,
Value = m.Value
}).ToList()
}).Skip(pageNumber*pageSize)
.Take(PageSize)
.ToList();
The relationship of an "author" to a document is implied, not enforced, at the data level. This solution keeps the entity models "pure" to the data representation and lets the code handle transforming that implied relationship into exposing a document's author.
The .Select() population can be handled by Automapper using .ProjectTo<TViewModel>().
By returning view models rather than entities you can avoid issues like this where .Include() operations get invalidated, plus avoid issues due to the temptation of detaching and reattaching entities between different contexts, plus improve performance and resource usage by only selecting and transmitting the data needed, and avoiding lazy load serialization issues if you forget to disable lazy-load or unexpected #null data with it.

How to update a Collection in Many-Many by assigning a new Collection?

In entity framework core 2.0, I have many-many relationship between Post and Category (the binding class is PostCategory).
When the user updates a Post, the whole Post object (with its PostCategory collection) is being sent to the server, and here I want to reassign the new received Collection PostCategory (the user may change this Collection significantly by adding new categories, and removing some categories).
Simplified code I use to update that collection (I just assign completely new collection):
var post = await dbContext.Posts
.Include(p => p.PostCategories)
.ThenInclude(pc => pc.Category)
.SingleOrDefaultAsync(someId);
post.PostCategories = ... Some new collection...; // <<<
dbContext.Posts.Update(post);
await dbContext.SaveChangesAsync();
This new collection has objects with the same Id of objects in the previous collection (e.g. the user removed some (but not all) categories). Because of the, I get an exception:
System.InvalidOperationException: The instance of entity type 'PostCategory' cannot be tracked because another instance with the same key value for {'CategoryId', 'PostId'} is already being tracked.
How can I rebuild the new collection (or simply assign a new collection) efficiently without getting this exception?
UPDATE
The answer in this link seems to be related to what I want, but it is a good and efficient method? Is there any possible better approach?
UPDATE 2
I get my post (to edit overwrite its values) like this:
public async Task<Post> GetPostAsync(Guid postId)
{
return await dbContext.Posts
.Include(p => p.Writer)
.ThenInclude(u => u.Profile)
.Include(p => p.Comments)
.Include(p => p.PostCategories)
.ThenInclude(pc => pc.Category)
.Include(p => p.PostPackages)
.ThenInclude(pp => pp.Package)
//.AsNoTracking()
.SingleOrDefaultAsync(p => p.Id == postId);
}
UPDATE 3 (The code in my controller, which tries to update the post):
var writerId = User.GetUserId();
var categories = await postService.GetOrCreateCategoriesAsync(
vm.CategoryViewModels.Select(cvm => cvm.Name), writerId);
var post = await postService.GetPostAsync(vm.PostId);
post.Title = vm.PostTitle;
post.Content = vm.ContentText;
post.PostCategories = categories?.Select(c => new PostCategory { CategoryId = c.Id, PostId = post.Id }).ToArray();
await postService.UpdatePostAsync(post); // Check the implementation in Update4.
UPDATE 4:
public async Task<Post> UpdatePostAsync(Post post)
{
// Find (load from the database) the existing post
var existingPost = await dbContext.Posts
.SingleOrDefaultAsync(p => p.Id == post.Id);
// Apply primitive property modifications
dbContext.Entry(existingPost).CurrentValues.SetValues(post);
// Apply many-to-many link modifications
dbContext.Set<PostCategory>().UpdateLinks(
pc => pc.PostId, post.Id,
pc => pc.CategoryId,
post.PostCategories.Select(pc => pc.CategoryId)
);
// Apply all changes to the db
await dbContext.SaveChangesAsync();
return existingPost;
}
The main challenge when working with disconnect link entities is to detect and apply the added and deleted links. And EF Core (as of the time of writing) provides little if no help to do that.
The answer from the link is ok (the custom Except method is too heavier for what it does IMO), but it has some traps - the existing links has to be retrieved in advance using the eager / explicit loading (though with EF Core 2.1 lazy loading that might not be an issue), and the new links should have only FK properties populated - if they contain reference navigation properties, EF Core will try to create new linked entities when calling Add / AddRange.
A while ago I answered similar, but slightly different question - Generic method for updating EFCore joins. Here is the more generalized and optimized version of the custom generic extension method from the answer:
public static class EFCoreExtensions
{
public static void UpdateLinks<TLink, TFromId, TToId>(this DbSet<TLink> dbSet,
Expression<Func<TLink, TFromId>> fromIdProperty, TFromId fromId,
Expression<Func<TLink, TToId>> toIdProperty, IEnumerable<TToId> toIds)
where TLink : class, new()
{
// link => link.FromId == fromId
Expression<Func<TFromId>> fromIdVar = () => fromId;
var filter = Expression.Lambda<Func<TLink, bool>>(
Expression.Equal(fromIdProperty.Body, fromIdVar.Body),
fromIdProperty.Parameters);
var existingLinks = dbSet.AsTracking().Where(filter);
var toIdSet = new HashSet<TToId>(toIds);
if (toIdSet.Count == 0)
{
//The new set is empty - delete all existing links
dbSet.RemoveRange(existingLinks);
return;
}
// Delete the existing links which do not exist in the new set
var toIdSelector = toIdProperty.Compile();
foreach (var existingLink in existingLinks)
{
if (!toIdSet.Remove(toIdSelector(existingLink)))
dbSet.Remove(existingLink);
}
// Create new links for the remaining items in the new set
if (toIdSet.Count == 0) return;
// toId => new TLink { FromId = fromId, ToId = toId }
var toIdParam = Expression.Parameter(typeof(TToId), "toId");
var createLink = Expression.Lambda<Func<TToId, TLink>>(
Expression.MemberInit(
Expression.New(typeof(TLink)),
Expression.Bind(((MemberExpression)fromIdProperty.Body).Member, fromIdVar.Body),
Expression.Bind(((MemberExpression)toIdProperty.Body).Member, toIdParam)),
toIdParam);
dbSet.AddRange(toIdSet.Select(createLink.Compile()));
}
}
It uses a single database query to retrieve the exiting links from the database. The overhead are few dynamically built expressions and compiled delegates (in order to keep the calling code simplest as possible) and a single temporary HashSet for fast lookup. The performance affect of the expression / delegate building should be negligible, and can be cached if needed.
The idea is to pass just a single existing key for one of the linked entities and list of exiting keys for the other linked entity. So depending of which of the linked entity links you are updating, it will be called differently.
In you sample, assuming you are receiving IEnumerable<PostCategory> postCategories, the process would be something like this:
var post = await dbContext.Posts
.SingleOrDefaultAsync(someId);
dbContext.Set<PostCategory>().UpdateLinks(pc =>
pc.PostId, post.Id, pc => pc.CategoryId, postCategories.Select(pc => pc.CategoryId));
await dbContext.SaveChangesAsync();
Note that this method allows you to change the requirement and accept IEnumerable<int> postCategoryIds:
dbContext.Set<PostCategory>().UpdateLinks(pc =>
pc.PostId, post.Id, pc => pc.CategoryId, postCategoryIds);
or IEnumerable<Category> postCategories:
dbContext.Set<PostCategory>().UpdateLinks(pc =>
pc.PostId, post.Id, pc => pc.CategoryId, postCategories.Select(c => c.Id));
or similar DTOs / ViewModels.
Category posts can be updated in a similar manner, with corresponding selectors swapped.
Update: In case you a receiving a (potentially) modified Post post entity instance, the whole update procedure cold be like this:
// Find (load from the database) the existing post
var existingPost = await dbContext.Posts
.SingleOrDefaultAsync(p => p.Id == post.Id);
if (existingPost == null)
{
// Handle the invalid call
return;
}
// Apply primitive property modifications
dbContext.Entry(existingPost).CurrentValues.SetValues(post);
// Apply many-to-many link modifications
dbContext.Set<PostCategory>().UpdateLinks(pc => pc.PostId, post.Id,
pc => pc.CategoryId, post.PostCategories.Select(pc => pc.CategoryId));
// Apply all changes to the db
await dbContext.SaveChangesAsync();
Note that EF Core uses separate database query for eager loading related collecttions. Since the helper method does the same, there is no need to Include link related data when retrieving the main entity from the database.

Entity Framework Include() is not working within complex query

Consider following LINQ query:
var item = (from obj in _db.SampleEntity.Include(s => s.NavProp1)
select new
{
ItemProp1 = obj,
ItemProp2 = obj.NavProp2.Any(n => n.Active)
}).SingleOrDefault();
This runs as expected, but item.ItemProp1.NavProp1 is NULL.
As it explains here this is because of the query actually changes after using Include(). but the question is what is the solution with this situation?
Edit:
When I change the query like this, every things works fine:
var item = (from obj in _db.SampleEntity.Include(s => s.NavProp1)
select obj).SingleOrDefault();
Regarding to this article I guess what the problem is... but the solution provided by author not working in my situation (because of using anonymous type in final select rather than entity type).
As you mentioned, Include is only effective when the final result of the query consists of the entities that should include the Include-d navigation properties.
So in this case Include has effect:
var list = _db.SampleEntity.Include(s => s.NavProp1).ToList();
The SQL query will contain a JOIN and each SampleEntity will have its NavProp1 loaded.
In this case it has no effect:
var list = _db.SampleEntity.Include(s => s.NavProp1)
.Select(s => new { s })
.ToList();
The SQL query won't even contain a JOIN, EF completely ignores the Include.
If in the latter query you want the SampleEntitys to contain their NavProp1s you can do:
var list = _db.SampleEntity
.Select(s => new { s, s.NavProp1 })
.ToList();
Now Entity Framework has fetched SampleEntitys and NavProp1 entities from the database separately, but it glues them together by a process called relationship fixup. As you see, the Include is not necessary to make this happen.
However, if Navprop1 is a collection, you'll notice that...
var navprop1 = list.First().s.Navprop1;
...will still execute a query to fetch Navprop1 by lazy loading. Why is that?
While relationship fixup does fill Navprop1 properties, it doesn't mark them as loaded. This only happens when Include loaded the properties. So now we have SampleEntity all having their Navprop1s, but you can't access them without triggering lazy loading. The only thing you can do to prevent this is
_db.Configuration.LazyLoadingEnabled = false;
var navprop1 = list.First().s.Navprop1;
(or by preventing lazy loading by disabling proxy creation or by not making Navprop1 virtual.)
Now you'll get Navprop1 without a new query.
For reference navigation properties this doesn't apply, lazy loading isn't triggered when it's enabled.
In Entity Framework core, things have changed drastically in this area. A query like _db.SampleEntity.Include(s => s.NavProp1).Select(s => new { s }) will now include NavProp1 in the end result. EF-core is smarter in looking for "Includable" entities in the end result. Therefore, we won't feel inclined to shape a query like Select(s => new { s, s.NavProp1 }) in order to populate the navigation property. Be aware though, that if we use such a query without Include, lazy loading will still be triggered when s.NavProp1 is accessed.
I know this will probably get a few laughs, but don't forget the obvious like i just did. The row in the database didn't actually have a foreign key reference! I should have checked the dam data first before thinking EF Include wasn't working! Grrr. 30 minutes of my life I won't get back.
If your model is defined properly it should work without any problems.
using System.Data.Entity;
var item = _db.SampleEntity
.Include(p => p.NavigationProperty)
.Select(p => new YourModel{
PropertyOne = p.Something,
PropertyTwo = p.NavigationProperty.Any(x => x.Active)
})
.SingleOrDefault(p => p.Something == true);
How did you find that item.ItemProp1.NavProp1 is null. EF uses proxies to load all required properties when you try to access it.
What about
var item = (from obj in _db.SampleEntity.Include(s => s.NavProp1)
select obj).SingleOrDefault();
Assert.IsNotNull(obj.NavProp1);
Assert.IsNotNull(obj.NavProp2);
You can also try with
var item = (from obj in _db.SampleEntity.Include(s => s.NavProp1)
select new
{
ItemProp1 = obj,
NavProp1 = obj.NavProp1,
ItemProp2 = obj.NavProp2.Any(n => n.Active)
}).SingleOrDefault();
Assert.IsNotNull(item.NavProp1)
Of course I assume that you don't have any problems with EF navigation property mappings.

Categories