Miguel
Miguel

Reputation: 1177

EF is including Child's reference back to Parent's siblings

I'm querying my Deliveries and including one of it's property (Material Type) and it's returning everything good except that my Material Type has a list of Deliveries. Therefore its returning Delivery siblings.

Here are my classes:

public class Delivery
{
    public int DeliveryId { get; set; }
    public DateTime DeliveryDate { get; set; }
    ...
    public int MaterialTypeId { get; set; }
    public virtual MaterialType MaterialType { get; set; }
}

public class MaterialType
{
    public int MaterialTypeId { get; set; }
    public string Name { get; set; }
    ...
    public virtual ICollection<Delivery> Deliveries { get; set; }
}

Here is my deliveries query by date range

var deliveries = DataStore.Filter<Delivery>(i =>
                 i.DeliveryDate >= startDate && i.DeliveryDate < endDate
                 ,new string[] { "MaterialType" }) // Includes
                 .OrderByDescending(i => i.DeliveryDate).ToList();

public virtual IQueryable<T> Filter<T>(Expression<Func<T, bool>> predicate, string[] includes = null) where T : class
{
    IQueryable<T> set = dbContext.Set<T>();
    if (includes != null && includes.Count() > 0)
    {
        foreach (var include in includes)
        {
            set = set.Include(include);
        }
    }
    return set.Where<T>(predicate).AsQueryable<T>();
}

Here are the results that I'm getting back from the query and the Delivery.MaterialType.Delivery is being populated back with the siblings of the original Delivery.

[{
    "DeliveryId": 1,
    "DeliveryDate": "2017-05-22",
    "MaterialTypeId": 2,
    "MaterialType": {
        "MaterialTypeId": 2,
        "Name": "Bulk",
        "Deliveries": [{
            "DeliveryId": 2,
            "DeliveryDate": "2017-05-22",
            "MaterialTypeId": 2,
        },
        {
            "DeliveryId": 3,
            "DeliveryDate": "2017-05-22",
            "MaterialTypeId": 2,
        }]
    }
}]

Lazy loading is set to disabled.

dbContext.Configuration.LazyLoadingEnabled = false;

Is there any way to prevent MaterialTypes from populating Deliveries?

Upvotes: 0

Views: 279

Answers (2)

Akos Nagy
Akos Nagy

Reputation: 4360

I'm not sure Lazy loading is at fault here, rather this might have to do something with the auto-wiring up of relationships.

So let's say that you have Delivery A with Material Type A, and Delivery B with Material Type A also. If you issue a query for the deliveries and include the material type, then the list of deliveries in Material Type A will contain both Delivery A and Delivery B, because they get loaded into the context as the result of the query anyways.

Disabling lazy loading only tells EF not to load any entities when accessing the property, but it does not say anything about fixing up the relationships between entities that are already in the context.

Same situation can happen if you issue multiple queries using the same DbContext object: once a query is run and the results are materialized, the objects are in the context. So if you issue another query with the same context where one of the resulting objects has a reference to the previously loaded entity, the navigation properties are populated automatically based on the objects that are in the context.

Upvotes: 2

Robert McKee
Robert McKee

Reputation: 21477

The object you are serializing has Lazy Loading enabled, so it is populating all the properties. Disable Lazy loading like this before your query:

DataStore.Configuration.LazyLoadingEnabled = false;

Upvotes: 0

Related Questions