I have an issue using EF7 in a web application with which I could use some help. I'm currently using EF7 RC1.
Here are some models that illustrate my problem.
Contact
public class Contact
{
public Guid Id { get; set; }
public string Desc { get; set; }
public ContactType ContactType { get; set; }
}
ContactType
public class ContactType
{
public Guid Id { get; set; }
public string Desc { get; set; }
public ICollection<Contact> Contacts { get; set; }
}
These models are related via Fluent API like this:
modelBuilder.Entity<Contact>(entity => {
// abridged for clarity
entity
.HasOne(c => c.ContactType)
.WithMany(ct => ct.Contacts)
.IsRequired();
});
My needs are to be able to retrieve a collection of Contact entities from the database with their ContactType property loaded. EF makes this quite easy:
using(var context = new MyDbContext()) {
var contacts = await context
.Contacts
.Include(c => c.ContactTypes)
.Where(/* some search criteria */)
.ToListAsync();
}
The issue is that in loading the ContactType properties of the Contact entities (which happens due to the call to .Include() in the query), EF also helpfully loads the Contacts property of each ContactType entity, resulting in an infinite chain of Contacts pointing at ContactTypes and ContactTypes pointing at Contacts. I understand why this is the default behavior and that it's helpful in many cases, but my needs are to serialize these entities to JSON and send them down to the client - it's a read-only situation.
My desired behavior is for EF to return a collection of Contacts with loaded (non-null) ContactType properties that have their Contacts property set to null. Is this something EF can do? Is there any way to end up with the object graph I want short of manually nulling out properties I don't want populated?
Things I've tried:
You can't avoid EF to load ContactType.Contacts collection, as it's not actually loading it but filling the collection with the loaded Contact instances. This is why using AsNoTracking has no efect, because is not a problem of lazy loading nor ChangeTracker.
You have three possible solutions:
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
, but as you stated it will generate lot of unnecesary data, as you will get the collection of Contacts for every ContactType[JsonIgnore]
attribute on ContactType.Contacts so it will be ignored by the serializer. But it will ignore it always, I don't know if you need it in other situationsI would prefer the 3rd option as I don't like sending domain model objects to the client, and it avoid adding attributes to domain model not related with domain.
I have same question Entity Framework 7 Core disable auto loading
I add AsNoTracking()
IQueryable<ScheduleModel> q = _db.Schedules;
q = q.AsNoTracking();
q = q.Include(x => x.ElementItem);
q = q.Include(x => x.ScheduleHours);
Properties not populate automatic now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With