-1

I have two related models.

    public class Offer
    {
        public long Id { get; set; }
        public string OfferCode { get; set; }
        public string Description { get; set; }

        // more properties

        public int ProductId { get; set; }
        public virtual Product Product { get; set; }
    }

    public class Product
    {
        public long Id { get; set; }
        public string Name { get; set; }

        // more properties

        public virtual ICollection<Offer> Offers { get; set; }
    }

I am trying to have an MVC form with a select HTML element where Offers are grouped and products and have the Product Names serve as optgroups. To this end, I have a view model that I intend to populate with the grouped Offers and I have a method to do just that.

        private OfferMessageViewModel PrepareViewModel(OfferMessageViewModel viewModel)
        {
            var offers = _context.Offers.Include(o => o.Product).ToList()
                .GroupBy(o => o.Product.Name).ToList();

            foreach (var offerGroup in offers)
            {
                var optionGroup = new SelectListGroup
                {
                    Name = offerGroup.Key
                };

                foreach (var offer in offerGroup)
                {
                    viewModel.Offers.Add(
                        new SelectListItem
                        {
                            Value = offer.OfferCode,
                            Text = offer.Description,
                            Group = optionGroup
                        }
                    );
                }
            }
            return viewModel;
        }

The code gets tripped up in the GroupBy clause. o.Product is null even when o.ProductID has a value in it.

The ToList() call right before the GroupBy is not helping.

I have tried removing the virtual modifiers on the related entities navigation properties but the error persisted.

Installing the NuGet package Microsoft.EntityFrameworkCore.Proxies and modifying and configuring it as such

services.AddDbContext<ApplicationDbContext>(options =>
                options.UseLazyLoadingProxies() 
                .UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));

also did not make the error go away.

Is there something else I am missing?

Any help would be greatly appreciated.

EDIT: It has been suggested that my post might be solved by this SO question. But I get the null reference exception even with lazy loading explicitly turned on. I have tried the suggested solutions there but still no luck.

Steve S
  • 509
  • 1
  • 11
  • 24
  • @AliK Forgive me but I thought _context.Offers.Include(o => o.Product) is exactly what that is doing. Including the related Product. Or am I missing something else? – Steve S Mar 24 '20 at 07:03
  • Try doing _context.Offers.Include("Product") instead – Mohammad Ali Mar 24 '20 at 07:10
  • Does this answer your question? [Entity Framework Include() is not working](https://stackoverflow.com/questions/4474951/entity-framework-include-is-not-working) – Mohammad Ali Mar 24 '20 at 07:14
  • @MohammadAli Thanks for the suggestions but those fixes don't work for me. – Steve S Mar 24 '20 at 07:32
  • @MohammadAli I found the fix. Posted it as the answer. Once again thanks for your suggestions. – Steve S Mar 26 '20 at 08:47

1 Answers1

1

I eventually solved it.

Apparently the problem was that the foreign key was an int referencing a primary key of type long.

So I changed

public int ProductId { get; set; }

to

public long ProductId { get; set; }

in the Offer model. Added the necessary migration, updated the database and now it works. No more null reference exceptions.

Don't know why I missed that but it's probably a combination of lack of sleep and a not-so-helpful error message throwing me off in a completely different direction.

Steve S
  • 509
  • 1
  • 11
  • 24