Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity framework core lazy loading not performed when inserting new instances

I have two classes:

  • Campaign which references a class customer:

    public class Campaign
    {
        [Key]
        [Required]
        public int id { get; set; }
        public int? CustomerId { get; set; }
        [ForeignKey("CustomerId")]
        public virtual Customer customer { get; set; }
    }
    
  • And Customer:

    public class Customer
    {
        [Key]
        [Required]
        public int id { get; set; }
        [Required]
        public string name { get; set; }
        [Required]
        public double turnover { get; set; }
        public virtual ICollection<Campaign> campaigns { get; set; }
    }
    

Here's is an insert method:

async Task<Campaign> ICampaignRepository.InsertCampaign(Campaign campaign)
{
    try
    {
        _context.Campaigns.Add(campaign);
        await _context.SaveChangesAsync();
        return campaign;
    }
    catch (Exception)
    {
        throw;
    }
}

I'm using Microsoft.EntityFrameworkCore.Proxies package for lazy loading.

After adding a campaign instance having a customerId, the customer is not lazy loaded in the inserted object. Please note that I tried to fetch the campaign by id before returning it, but the problem persists, and I want to avoid loading the customer explicitly.

Lazy loading is perfectly working when performing fetch operations on existing records.

like image 700
khalil Avatar asked Jul 24 '19 09:07

khalil


People also ask

How do I enable lazy loading in Entity Framework?

Lazy loading means delaying the loading of related data, until you specifically request for it. When using POCO entity types, lazy loading is achieved by creating instances of derived proxy types and then overriding virtual properties to add the loading hook.

Does EF core use lazy loading by default?

Lazy Loading is the default behavior of LINQ that's why it is the default behavior of EF Core. With lazy loading, all related entities are not loaded along with the parent entity automatically.


1 Answers

Thanks to poke

The solution is to:

  1. Create a proxy for your entity using CreateProxy:

    Campaign toCreate = _context.Campaigns.CreateProxy();
    
  2. Transfer new values to your proxy object:

    _context.Entry(toCreate).CurrentValues.SetValues(Campaign);
    
  3. Finally, save your proxy object to the context:

    _context.Add(toCreate);
    await _context.SaveChangesAsync();`
    

Here's the full method:

async Task<Campaign> ICampaignRepository.InsertCampaign(Campaign campaign)
{
    Campaign toCreate = _context.Campaigns.CreateProxy();
    _context.Entry(toCreate).CurrentValues.SetValues(campaign);
    _context.Add(toCreate);
    await _context.SaveChangesAsync();
    return toCreate;
}
like image 61
khalil Avatar answered Oct 28 '22 18:10

khalil