ASP.NET Core Web API - Entity Relation Problem

raysefo

Well-known member
Joined
Feb 22, 2019
Messages
361
Programming Experience
10+
Hi,

I am upgrading my legacy ASP.NET web API to Core. This upgrading process is harder than I expected. The problem I'm having now is, this query gets the GameBank and GameBankPin in my legacy application. But the same code doesn't work in the Core application, unfortunately. GameBankPin is NULL.

Legacy:
Legacy 2022-12-25 081544.png


Core 6:
Core 2022-12-25 081823.png


Query:
C#:
     var gameBankResult =
       //Query GameBank database
       _unitOfWork.GameBankRepository.GetGames(g =>
       g.productCode == requestDto.productCode && g.referenceId == Guid.Empty);

Entities:
C#:
public class GameBank
     {
         public int GameBankID { get; set; }
         public Guid referenceId { get; set; }
         [DisplayName("Product Code")]
         public string productCode { get; set; }
         public int quantity { get; set; }
         public string? version { get; set; }
         public DateTime? requestDateTime { get; set; } = DateTime.Now;
         public int? customerID { get; set; }
         public string? password { get; set; }
         public DateTime? responseDateTime { get; set; } = DateTime.Now;
         public string? initiationResultCode { get; set; }
         public string? companyToken { get; set; }
         [DisplayName("Reconciled")]
         public int used { get; set; }
         [DisplayName("Description")]
         public string? productDescription { get; set; }
         public string? currency { get; set; }
         [DisplayName("Unit Price")]
         public double unitPrice { get; set; }
         public double totalPrice { get; set; }
         public string? ApplicationCode { get; set; }
         public double estimateUnitPrice { get; set; }
         public string? validatedToken { get; set; }
         public string? signature { get; set; }
         [DisplayName("Confirm/Cancel Status")]
         public int status { get; set; }
         public virtual List<GameBankPin> coupons { get; set; }
         public string? clientTrxRef { get; set; }
     }
 public class GameBankPin
     {
         public int Id { get; set; }
         public int GameBankID { get; set; }
         public DateTime? expiryDate { get; set; }
         public string Serial { get; set; }
         public string Pin { get; set; }
         public virtual GameBank GameBanks { get; set; }
     }
 
Hopefully some EF users can chime in, but don't you have to tell EF that you want child objects to be also be loaded in? Or does it automatically load up to a certain depth automatically?
 
Also, I vaguely recall that EF uses some kind of naming convention to automatically figure out relationships between entities and create the needed foreign keys. If your members don't fit the naming convention, attributes need to be added to the appropriate members to tell EF the relationship.

So it may be worth checking the database to ensure that EF really did setup the foreign keys, and the values in the tables look reasonable.
 
Moving to Entity Framework. This is not an ASP.NET Core WebAPI issue.
 
Also, I vaguely recall that EF uses some kind of naming convention to automatically figure out relationships between entities and create the needed foreign keys. If your members don't fit the naming convention, attributes need to be added to the appropriate members to tell EF the relationship.

So it may be worth checking the database to ensure that EF really did setup the foreign keys, and the values in the tables look reasonable.
The database was already there, It was working with the legacy asp.net web API. I am trying to upgrade to ASP.NET Core Web API.
 
Hopefully some EF users can chime in, but don't you have to tell EF that you want child objects to be also be loaded in? Or does it automatically load up to a certain depth automatically?
It depends on how you ask, but generally you have to be explicit about what you want
 
Is it because EF Core does not implement lazy loading by default?
You never show us the interesting part of the code, so we can't really tell you

unitOfWork.GameBankRepository.GetGames

This isn't EF Core; gamebank repository is your [unnecessary] wrapper around EF Core. I can't see the code of GetGames, so I can't tell you why the database operation doesn't download what you're expecting but I'd make a stab it it being something along the lines of

Your code should look like this but doesn't:

C#:
    var x = context.GameBanks.Include(gb => gb.coupons).Where(gb => gb.productCode == requestDto.productCode && gb.referenceId == Guid.Empty).ToList();

I'd dearly love it if your data model graph names were fixed up to comply with C# conventions - PascalCase for properties and not using plurals for singulars etc (GameBank GameBanks -> should have a plural name, implies a collation, but isn't a collection; always makes code read weird)
 
It was working with the legacy asp.net web API. I am trying to upgrade to ASP.NET Core Web API.
Was the legacy code using Entity Framework?
 
You never show us the interesting part of the code, so we can't really tell you



This isn't EF Core; gamebank repository is your [unnecessary] wrapper around EF Core. I can't see the code of GetGames, so I can't tell you why the database operation doesn't download what you're expecting but I'd make a stab it it being something along the lines of

Your code should look like this but doesn't:

C#:
    var x = context.GameBanks.Include(gb => gb.coupons).Where(gb => gb.productCode == requestDto.productCode && gb.referenceId == Guid.Empty).ToList();

I'd dearly love it if your data model graph names were fixed up to comply with C# conventions - PascalCase for properties and not using plurals for singulars etc (GameBank GameBanks -> should have a plural name, implies a collation, but isn't a collection; always makes code read weird)
The secret code:
C#:
public virtual List<TEntity> GetGames(Expression<Func<TEntity, bool>> where)
{
   return DbSet.Where(where).ToList();
}
 
Yes, not the core but EF.
Ah! I see now why you feel like there is a major regression. Since I've had issues with EF before, I'm not exactly surprised that something may have been broken between versions.
 
Is it because EF Core does not implement lazy loading by default?
Looks like for EF Core, you need to explicitly opt-in to lazy loading by adding another Nuget package.
 
I added NuGet for lazy loading as follows:
C#:
     builder.Services.AddDbContext<OyunPalasDbContext>(
         options => options.UseLazyLoadingProxies().UseSqlServer("name=ConnectionStrings:OyunPalasDbContext"));

But getting this error now:
C#:
Cannot insert explicit value for identity column in table 'Coupons' when IDENTITY_INSERT is set to OFF.

it shouldn't be this hard to upgrade.
 
Back
Top Bottom