locked
Issue with scaffolding asp.net razor pages using an entity framework core dbcontext inside a separate class library RRS feed

  • Question

  • User711064532 posted

    Technical details:

    MySQL version: mariadb Ver 15.1 Distrib 10.4.10-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2

    Operating system: Ubuntu 18.04 LTS

    Pomelo.EntityFrameworkCore.MySql version: 3.0.0

    Microsoft.AspNetCore.App version: 3.0

    Problem statement:

    Unable to scaffold asp.net razor pages with the dbContext residing in class library.

    Steps to reproduce:

    1. Create a class library for DAL

    2. Create an asp.net razor application.

    3. Reference the dal project in ui project.

    4. Include below references in DAL project file.

    <Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
    <TargetFramework>netstandard2.1</TargetFramework>
    </PropertyGroup>

    <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0">
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0">
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.0.0" />
    </ItemGroup>
    </Project>

    5. Run below command to scaffold entities using database first approach:

    dotnet ef dbcontext scaffold "Server=localhost;Port=3306;User ID=root;Password=secure_password;Database=Food;Pooling=true;" "Pomelo.EntityFrameworkCore.MySql" --startup-project ../FoodV2.UI/ -c FoodDbContext --output-dir Models

    6. Auto generated entity class file:

    using System;
    using System.Collections.Generic;

    namespace FoodV2.Dal.Models
    {
    public partial class TblUnitOfMeasurement
    {
    public sbyte Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string Tag { get; set; }
    public string Unit { get; set; }
    public string Symbol { get; set; }
    public string SystemOfMeasurement { get; set; }
    public bool? IsActive { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime? ModifiedOn { get; set; }
    }
    }

    7. Auto generated dbContext class file:

    using System;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Metadata;

    namespace FoodV2.Dal.Models
    {
    public partial class FoodDbContext : DbContext
    {
    public FoodDbContext()
    {
    }

    public FoodDbContext(DbContextOptions<FoodDbContext> options)
    : base(options)
    {
    }

    public virtual DbSet<TblFood> TblFood { get; set; }
    public virtual DbSet<TblFoodType> TblFoodType { get; set; }
    public virtual DbSet<TblHealthBenefit> TblHealthBenefit { get; set; }
    public virtual DbSet<TblIllness> TblIllness { get; set; }
    public virtual DbSet<TblNutrients> TblNutrients { get; set; }
    public virtual DbSet<TblNutrientsType> TblNutrientsType { get; set; }
    public virtual DbSet<TblSideEffect> TblSideEffect { get; set; }
    public virtual DbSet<TblUnitOfMeasurement> TblUnitOfMeasurement { get; set; }

    // Unable to generate entity type for table 'tblFood2Nutrients'. Please see the warning messages.
    // Unable to generate entity type for table 'tblFoodHealthBenefit'. Please see the warning messages.
    // Unable to generate entity type for table 'tblFoodSideEffect'. Please see the warning messages.
    // Unable to generate entity type for table 'tblFoodToCure'. Please see the warning messages.
    // Unable to generate entity type for table 'tblNutrientsHealthBenefit'. Please see the warning messages.
    // Unable to generate entity type for table 'tblNutrientsSideEffect'. Please see the warning messages.
    // Unable to generate entity type for table 'tblNutrientsToCure'. Please see the warning messages.

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
    if (!optionsBuilder.IsConfigured)
    {

    }
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    modelBuilder.Entity<TblFood>(entity =>
    {
    entity.ToTable("tblFood");

    entity.HasIndex(e => e.FoodTypeId)
    .HasName("tblFood_FK");

    entity.Property(e => e.Id)
    .HasColumnName("ID")
    .HasColumnType("int(11)");

    entity.Property(e => e.CreatedOn)
    .HasColumnType("timestamp")
    .HasDefaultValueSql("'current_timestamp()'")
    .ValueGeneratedOnAddOrUpdate();

    entity.Property(e => e.Description).HasColumnType("varchar(300)");

    entity.Property(e => e.FoodTypeId)
    .HasColumnName("FoodTypeID")
    .HasColumnType("smallint(6)");

    entity.Property(e => e.ImageUrl).HasColumnType("varchar(500)");

    entity.Property(e => e.IsActive)
    .IsRequired()
    .HasColumnType("bit(1)")
    .HasDefaultValueSql("'b\\'1\\''");

    entity.Property(e => e.ModifiedOn).HasColumnType("timestamp");

    entity.Property(e => e.Title)
    .IsRequired()
    .HasColumnType("varchar(100)");

    entity.HasOne(d => d.FoodType)
    .WithMany(p => p.TblFood)
    .HasForeignKey(d => d.FoodTypeId)
    .OnDelete(DeleteBehavior.ClientSetNull)
    .HasConstraintName("tblFood_FK");
    });

    modelBuilder.Entity<TblFoodType>(entity =>
    {
    entity.ToTable("tblFoodType");

    entity.Property(e => e.Id)
    .HasColumnName("ID")
    .HasColumnType("smallint(6)");

    entity.Property(e => e.CreatedOn)
    .HasColumnType("timestamp")
    .HasDefaultValueSql("'current_timestamp()'")
    .ValueGeneratedOnAddOrUpdate();

    entity.Property(e => e.Description).HasColumnType("varchar(300)");

    entity.Property(e => e.ImageUrl).HasColumnType("varchar(150)");

    entity.Property(e => e.IsActive)
    .IsRequired()
    .HasColumnType("bit(1)")
    .HasDefaultValueSql("'b\\'1\\''");

    entity.Property(e => e.ModifiedOn).HasColumnType("timestamp");

    entity.Property(e => e.Title)
    .IsRequired()
    .HasColumnType("varchar(50)");
    });

    modelBuilder.Entity<TblHealthBenefit>(entity =>
    {
    entity.ToTable("tblHealthBenefit");

    entity.Property(e => e.Id)
    .HasColumnName("ID")
    .HasColumnType("int(11)");

    entity.Property(e => e.CreatedOn)
    .HasColumnType("timestamp")
    .HasDefaultValueSql("'current_timestamp()'")
    .ValueGeneratedOnAddOrUpdate();

    entity.Property(e => e.ImageUrl).HasColumnType("varchar(150)");

    entity.Property(e => e.IsActive)
    .IsRequired()
    .HasColumnType("bit(1)")
    .HasDefaultValueSql("'b\\'1\\''");

    entity.Property(e => e.ModifiedOn).HasColumnType("timestamp");

    entity.Property(e => e.Title)
    .IsRequired()
    .HasColumnType("varchar(150)");
    });

    modelBuilder.Entity<TblIllness>(entity =>
    {
    entity.ToTable("tblIllness");

    entity.Property(e => e.Id)
    .HasColumnName("ID")
    .HasColumnType("int(11)");

    entity.Property(e => e.CreatedOn)
    .HasColumnType("timestamp")
    .HasDefaultValueSql("'current_timestamp()'")
    .ValueGeneratedOnAddOrUpdate();

    entity.Property(e => e.ImageUrl).HasColumnType("varchar(150)");

    entity.Property(e => e.IsActive)
    .HasColumnType("bit(1)")
    .HasDefaultValueSql("'b\\'1\\''");

    entity.Property(e => e.ModifiedOn).HasColumnType("timestamp");

    entity.Property(e => e.Title)
    .IsRequired()
    .HasColumnType("varchar(150)");
    });

    modelBuilder.Entity<TblNutrients>(entity =>
    {
    entity.ToTable("tblNutrients");

    entity.HasIndex(e => e.NutrientsTypeId)
    .HasName("tblNutrients_FK");

    entity.Property(e => e.Id)
    .HasColumnName("ID")
    .HasColumnType("smallint(6)");

    entity.Property(e => e.CreatedOn)
    .HasColumnType("timestamp")
    .HasDefaultValueSql("'current_timestamp()'")
    .ValueGeneratedOnAddOrUpdate();

    entity.Property(e => e.Description).HasColumnType("varchar(300)");

    entity.Property(e => e.ImageUrl).HasColumnType("varchar(150)");

    entity.Property(e => e.IsActive)
    .IsRequired()
    .HasColumnType("bit(1)")
    .HasDefaultValueSql("'b\\'1\\''");

    entity.Property(e => e.ModifiedOn).HasColumnType("timestamp");

    entity.Property(e => e.NutrientsTypeId)
    .HasColumnName("NutrientsTypeID")
    .HasColumnType("smallint(6)");

    entity.Property(e => e.Title)
    .IsRequired()
    .HasColumnType("varchar(50)");

    entity.HasOne(d => d.NutrientsType)
    .WithMany(p => p.TblNutrients)
    .HasForeignKey(d => d.NutrientsTypeId)
    .OnDelete(DeleteBehavior.ClientSetNull)
    .HasConstraintName("tblNutrients_FK");
    });

    modelBuilder.Entity<TblNutrientsType>(entity =>
    {
    entity.ToTable("tblNutrientsType");

    entity.Property(e => e.Id)
    .HasColumnName("ID")
    .HasColumnType("smallint(6)");

    entity.Property(e => e.CreatedOn)
    .HasColumnType("timestamp")
    .HasDefaultValueSql("'current_timestamp()'")
    .ValueGeneratedOnAddOrUpdate();

    entity.Property(e => e.Description).HasColumnType("varchar(300)");

    entity.Property(e => e.ImageUrl).HasColumnType("varchar(150)");

    entity.Property(e => e.IsActive)
    .IsRequired()
    .HasColumnType("bit(1)")
    .HasDefaultValueSql("'b\\'1\\''");

    entity.Property(e => e.ModifiedOn).HasColumnType("timestamp");

    entity.Property(e => e.Title)
    .IsRequired()
    .HasColumnType("varchar(50)");
    });

    modelBuilder.Entity<TblSideEffect>(entity =>
    {
    entity.ToTable("tblSideEffect");

    entity.Property(e => e.Id)
    .HasColumnName("ID")
    .HasColumnType("int(11)");

    entity.Property(e => e.CreatedOn)
    .HasColumnType("timestamp")
    .HasDefaultValueSql("'current_timestamp()'")
    .ValueGeneratedOnAddOrUpdate();

    entity.Property(e => e.ImageUrl).HasColumnType("varchar(150)");

    entity.Property(e => e.IsActive)
    .IsRequired()
    .HasColumnType("bit(1)")
    .HasDefaultValueSql("'b\\'1\\''");

    entity.Property(e => e.ModifiedOn).HasColumnType("timestamp");

    entity.Property(e => e.Title)
    .IsRequired()
    .HasColumnType("varchar(150)");
    });

    modelBuilder.Entity<TblUnitOfMeasurement>(entity =>
    {
    entity.ToTable("tblUnitOfMeasurement");

    entity.Property(e => e.Id)
    .HasColumnName("ID")
    .HasColumnType("tinyint(4)");

    entity.Property(e => e.CreatedOn)
    .HasColumnType("timestamp")
    .HasDefaultValueSql("'current_timestamp()'")
    .ValueGeneratedOnAddOrUpdate();

    entity.Property(e => e.Description)
    .IsRequired()
    .HasColumnType("varchar(500)");

    entity.Property(e => e.IsActive)
    .IsRequired()
    .HasColumnType("bit(1)")
    .HasDefaultValueSql("'b\\'1\\''");

    entity.Property(e => e.ModifiedOn).HasColumnType("timestamp");

    entity.Property(e => e.Symbol)
    .IsRequired()
    .HasColumnType("varchar(10)");

    entity.Property(e => e.SystemOfMeasurement)
    .IsRequired()
    .HasColumnType("varchar(50)");

    entity.Property(e => e.Tag)
    .IsRequired()
    .HasColumnType("varchar(100)");

    entity.Property(e => e.Title)
    .IsRequired()
    .HasColumnType("varchar(50)");

    entity.Property(e => e.Unit)
    .IsRequired()
    .HasColumnType("varchar(50)");
    });
    }
    }
    }

    8. Include below references in UI project:

    <Project Sdk="Microsoft.NET.Sdk.Web">

    <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    </PropertyGroup>

    <ItemGroup>
    <ProjectReference Include="..\FoodV2.Dal\FoodV2.Dal.csproj" />
    </ItemGroup>

    <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0">
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0">
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.0" />
    <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.0.0" />
    </ItemGroup>

    </Project>

    9. Include below code in startup.cs file:

    public void ConfigureServices(IServiceCollection services)
    {
    services.AddRazorPages();

    services.AddDbContext<Dal.Models.FoodDbContext>(options => options.UseMySql(Configuration.GetConnectionString("MariadbConnection")));
    }
    10. Switch to UI project directory in terminal.

    11. Run below command on temrinal:

    dotnet aspnet-codegenerator razorpage -m TblUnitOfMeasurement -dc ../FoodV2.Dal.Models.FoodDbContext -udl -outDir Areas/Admin/Pages/UnitOfMeasurement -namespace FoodV2.UI.Areas.Admin.Pages.UnitOfMeasurement -scripts

    Output of command execution:

    Building project ...
    Finding the generator 'razorpage'...
    Running the generator 'razorpage'...
    Sequence contains more than one matching element
    at System.Linq.ThrowHelper.ThrowMoreThanOneMatchException()
    at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
    at Microsoft.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
    at Microsoft.VisualStudio.Web.CodeGeneration.ActionInvoker.Execute(String[] args)
    at Microsoft.VisualStudio.Web.CodeGeneration.CodeGenCommand.Execute(String[] args)
    RunTime 00:00:03.25

    Friday, November 15, 2019 11:42 AM

All replies

  • User711641945 posted

    Hi Yuvaraj Velmurugan,

    Could you share a simple demo about your project that could reproduce your issue?

    And why do you use class library which TargetFramework is netstandard2.1 instead of netcoreapp3.0?

    Best Regards,

    Rena

    Monday, November 18, 2019 10:02 AM
  • User711064532 posted

    Hello Rena,

    Thanks for the reply.

    I have updated my initial post.

    When i created the class library project, by default it was using targetframework netstandard2.0

    When i switched targetframework to netcoreapp3.0, it still gives the same error.

    Thursday, November 21, 2019 10:25 AM
  • User711641945 posted

    Hi Yuvaraj,

    >//Unable to generate entity type for table 'tblFood2Nutrients'. Please see the warning messages.

    Did you do not generate entity type for all of the tables in database successfully?

    Best Regards,

    Rena

    Friday, November 29, 2019 8:49 AM
  • User711064532 posted
    Those were lookup tables. Entity framework core will not generate code for lookup tables. But i created them manually and included required relationship. I am able to fetch data. But unable to scaffold UI with any of the model.
    Friday, November 29, 2019 9:52 AM