dotnet / Scaffolding

Code generators to speed up development.
MIT License
641 stars 229 forks source link

scaffolder doesn't use plural from DbSet #633

Closed Rick-Anderson closed 6 years ago

Rick-Anderson commented 7 years ago

new shorter instructions

  1. Create a RP web app named RazorPagesMovie
  2. Follow these instructions EXCEPT - name the DbSet plural public DbSet<Movie> Movies { get; set; }

This tutorial had 30K confirming it works until an update was made to change to the plural public DbSet<Movie> Movies { get; set; }

-- what follows is essentially the same instructions

In VS, create a new Razor Pages (RP) app named ContosoUniversity Create a Models folder. In the Models folder, create a class file named Student.cs and replace the code with the following:

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
    public class Student
    {
        public int ID { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }
    }
}

In the Data folder create a new class file named SchoolContext.cs, and replace the template code with the following code:

using ContosoUniversity.Models;
using Microsoft.EntityFrameworkCore;

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

        public DbSet<Student> Students { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            modelBuilder.Entity<Student>().ToTable("Student");
        }
    }
}

Add SchoolContext to the DI container:

// ADD EF using
// using Microsoft.EntityFrameworkCore;

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<Data.SchoolContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddMvc();
}

Open the appsettings.json file and add a connection string as shown in the following code:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=ContosoUniversity1;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  }
}

In the Package Manager Console (PMC), enter the following commands:

Install-Package Microsoft.VisualStudio.Web.CodeGeneration.Design -Version 2.0.0
Add-Migration Initial
Update-Database

*Scaffold the model

dotnet aspnet-codegenerator razorpage -m Student -dc SchoolContext -udl -outDir Pages\CU --referenceScriptLibraries

Build the project. You get errors error CS1061: 'SchoolContext' does not contain a definition for 'Student' and no extension method 'Student'

Here is the generated code: _context.Student.Add(Student); It should be plural _context.Students.Add(Student);

mikebrind commented 7 years ago

Related to the issue outlined, the scaffolder also generates singular names for collection properties on page model classes, which is odd, in my opinion. So instead of

public IList<Student> Students { get; set; }

you get

public IList<Student> Student { get; set; }

And in the Razor Page:

@foreach (var item in Model.Student) {
Eilon commented 6 years ago

@prafullbhosale what is the reason to patch this? Is it just a bug, or is it really a new feature?

Rick-Anderson commented 6 years ago

@Eilon sorry for the verbose write up. The scaffolder generates incorrect code when the DbSet is plural.

public DbSet<Student> Students { get; set; }

Eilon commented 6 years ago

Ah ok so it's a genuine, old-fashioned, plain & simple bug then?

Eilon commented 6 years ago

Talked to @mlorbetske about this. It's indeed worth fixing, but given the timelines, we are moving this issue to the March 2018 patch.

Rick-Anderson commented 6 years ago

Yes. Most folks like to use plural for the DbSet, but doing so generates invalid code. See Scaffold the model

Build the project. The build generates errors like the following:

1>Pages\Students\Index.cshtml.cs(26,38,26,45): error CS1061: 'SchoolContext' does not contain a definition for 'Student'

Globally change _context.Student to _context.Students (that is, add an "s" to Student). 7 occurrences are found and updated. We hope to fix this bug in the next release.

prafullbhosale commented 6 years ago

Ah ok so it's a genuine, old-fashioned, plain & simple bug then?

Yes this was a bug.

Talked to @mlorbetske about this. It's indeed worth fixing, but given the timelines, we are moving this issue to the March 2018 patch.

The fix for this is already in the placeholder branch for 2.0.x #667

Eilon commented 6 years ago

@prafullbhosale please discuss with @mlorbetske whether you two agree it is safe to take for this patch. I'm fine either way.

mlorbetske commented 6 years ago

@Eilon I talked this over with @prafullbhosale and reviewed the changes. It looks like this is low risk & could be taken for this release.

Eilon commented 6 years ago

Okie dokie, approved for 2.0.6.

philysworld commented 6 years ago

how do you fix this error from happening, what and where would i change the text?, having a hard time understanding what this means Globally change _context.Student to _context.Students (that is, add an "s" to Student).

i get this error ble to create an object of type 'SchoolContext'. Add an implementation of 'IDesignTimeDbContextFactory<SchoolContext

Rick-Anderson commented 6 years ago

@philysworld This issue fixes the problem and has nothing directly to do with my tutorial. Globally means in every file where _context.Student occurs. If you're using Visual Studio:

philysworld commented 6 years ago

i just used the mvc example seems to be easier

Rolito2009 commented 6 years ago

Thank you Rick, your tutorials are the best I could find. The last clarification on how to proceed was what I needed. Some of us need as much detail as possible to fully understand the issue and how to fix it.

mwhitis commented 6 years ago

@Eilon - you mentioned earlier that this was targeted for the March patch. Can you comment on whether or not that happened?

guardrex commented 6 years ago

@mwhitis According to https://github.com/aspnet/Scaffolding/pull/676, yes ... it was fixed. This issue (#633) was fixed on https://github.com/aspnet/Scaffolding/pull/667.