Search code examples
c#entity-framework-coreasp.net-core-mvcasp.net-core-8

Why are the data relations not working in C#?


I have a project with two tables, Loans and LoanTypes, and as shown below I've set them up with model classes. The problem is in my controller: when I list loans, there is no LoansType for this loan.

Loans model class:

namespace ACB.Models
{
    public class Loans
    {
        public ulong? LoansID { get; set; }
        public string? FullName { get; set; }

        [ForeignKey("LoanTypesID")]
        public ulong LoanTypesID { get; set; }  // relation ulong
        public LoanTypes LoanTypes { get; set; } 
    }
}

LoanTypes model class:

namespace ACB.Models
{
    public class LoanTypes 
    {
        public ulong? LoanTypesID { get; set; }
        public string? Name { get; set; }
        public string Profit { get; set; }

        public ICollection<Loans> Loanss { get; } = new List<Loans>();
    }
}

This is in the controller's action method:

var loan = _context.Loans
                   .Where(x => x.AccountsID == creditorAccountId)
                   .FirstOrDefault();

// Calculate Profit based on loan type
if (loan.LoanTypes.Type == "fixed")
{
    loan.Profit = Convert.ToInt64(Convert.ToDecimal(loan.LoanTypes.Profit));
}
else if (loan.LoanTypes.Type == "countable")
{
    if (Convert.ToInt64(Convert.ToDecimal(loan.LoanTypes.Profit)) > 0 && 
        Convert.ToInt64(Convert.ToDecimal(loan.LoanTypes.Profit)) < 1)
    {
        long max = Convert.ToInt64((loan.LoanAmount * Convert.ToInt64(Convert.ToDecimal(loan.LoanTypes.Profit))) / 12);
        long min = Convert.ToInt64((loan.Capital * Convert.ToInt64(Convert.ToDecimal(loan.LoanTypes.Profit))) / 12);
        loan.Profit = max + min / 2;
    }
}

In the DbContext :

namespace ACB.Data
{
    public class ACBDbContext : DbContext
    {
        public ACBDbContext(DbContextOptions<ACBDbContext> options) : base(options)
        {
        }

        public DbSet<Loans> Loans { get; set; }
        public DbSet<LoanTypes> LoanTypes { get; set; }

        public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            return await base.SaveChangesAsync(cancellationToken);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Loans>()
                        .ToTable("loans");

            modelBuilder.Entity<LoanTypes>()
                        .ToTable("loanTypes")
                        .HasMany(a => a.Loanss)
                        .WithOne(b => b.LoanTypes);
           
            // Consider configuring indexes and relationships for efficient querying

            modelBuilder.Entity<LoanTypes>()
                        .HasMany(b => b.Loanss)
                        .WithOne(p => p.LoanTypes)
                        .HasForeignKey(p => p.LoanTypesID);
        }

        public async Task<T> GetByIdAsync<T>(int id, CancellationToken cancellationToken = default) where T : class
        {
            var dbSet = this.Set<T>();
            return await dbSet.FindAsync(new object[] { id }, cancellationToken);
        }
    }
}

I'm working with ASP.NET Core 8 MVC and Entity Framework Core 8.


Solution

  • I did solve the problem with Eager loading not by Include but by following code:

    var paginatedList = await PaginatedList<Loan>.CreateAsync(data.AsNoTracking(), pageIndex, pageSize);
            paginatedList.ForEach(x => 
            {
                x.LoanTypes= _context.LoanTypes.First(y => y.LoanTypesID== x.LoanTypesID);
            });
    

    By this way of intilazing related data it is eager loading way. Thanks all for your awnsers and comments.