0

I'm working on project based on ASP.NET Core with Entity Framework core. I use generic repository pattern here. When I retrieve on specific object few object are retrieved with the same but some are not load. Please refer the following screen shots.

Please refer the following for the pattern implementation:

enter image description here

Please refer the debugger view below:

enter image description here

Above image shows that this object retrieves the "Offer" but not "Location".

Refer the following image for the "OfferLocation" class:

enter image description here

Any ideas about this situation?

Community
  • 1
  • 1
Oshadha
  • 546
  • 10
  • 25

2 Answers2

1

In your code you are requesting Offer and tell the EF.Core to include OfferLocations property. The OfferLocation references back the requested Offer object this why it got set. If you want to have Location to be included in this request you have to use ThenInclude method right after Include one. E.g. if you were using the database context to retrieve the data it could look like this:

context.Offers
    .Include(o => o.OfferLocations)
        .ThenInclude(ol => ol.Location)
    .FirstOrDefaultAsync(o => o.Id == id);

But with the generic repository approach you pass the collection of include expressions as the Expression<Func<T, object>>[] includeExpression which obviously doesn't let you use ThenInclude.

You can use the approach described in this answer.

public Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate = null,
                                         Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null,
                                         CancellationToken cancellationToken = default)
{
    IQueryable<TEntity> query = this.DbSet;

    if (include != null)
    {
        query = include(query);
    }

    if (predicate != null)
    {
        query = query.Where(predicate);
    }

    return query.FirstOrDefaultAsync(cancellationToken);
}

Usage:

var offer = await this.unitOfWork.Offers.FirstOrDefaultAsync(
    predicate: o => o.Id == id,
    include: source => source
        .Include(o => o.Partner)
        .Include(o => o.SubCategory)
        .Include(o => o.Category)
        .Include(o => o.OfferItems)
        .Include(o => o.OfficeLocations)
            .ThenInclude(ol => ol.Location));
Alexey Andrushkevich
  • 5,992
  • 2
  • 34
  • 49
0

You just have to use this package.

Microsoft.EntityFrameworkCore.Proxies

And in the context use this line of code.

protected override void OnConfiguring (DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseLazyLoadingProxies ();
}

This package automatic include when you use other Collection.

Oshadha
  • 546
  • 10
  • 25
mohamad mazaheri
  • 122
  • 1
  • 12
  • for learn how to use go to link https://stackoverflow.com/questions/55234943/what-is-the-equivalent-of-configuration-proxycreationenabled-in-ef-core – mohamad mazaheri Aug 28 '19 at 06:10
  • As you see on the screenshot it loads one of the object(Offer) which is in this collection, but it doesn't load the "Location" object. – Oshadha Aug 28 '19 at 06:13