interactive icon indicating copy to clipboard operation
interactive copied to clipboard

Add the option to select the tables/schemas used by --create-dbcontext

Open AutumnEvans418 opened this issue 1 year ago • 0 comments

Is your feature request related to a problem? Please describe. I have a large database where some tables don't work with the scaffolding. Namely, I get the error message: System.InvalidOperationException: The key {'Id'} cannot be added to keyless type 'Table (Dictionary<string, object>)'.

Describe the solution you'd like I would like an option to enter the tables and schemas like so: #!connect mssql --create-dbcontext --tables User,Order --schemas dbo --kernel-name name connection

Describe alternatives you've considered The only workaround I see is not using this feature and building the DbContext from scratch, or taking the following code and copying/pasting the output into the notebook, which is very ugly:


var services = new ServiceCollection();
services.AddEntityFrameworkDesignTimeServices();
var providerAssembly = Assembly.Load("Microsoft.EntityFrameworkCore.SqlServer");
var providerServicesAttribute = providerAssembly.GetCustomAttribute<DesignTimeProviderServicesAttribute>();
var providerServicesType = providerAssembly.GetType(providerServicesAttribute.TypeName);
var providerServices = (IDesignTimeServices)Activator.CreateInstance(providerServicesType);
providerServices.ConfigureDesignTimeServices(services);

var serviceProvider = services.BuildServiceProvider();
var scaffolder = serviceProvider.GetService<IReverseEngineerScaffolder>();

var model = scaffolder.ScaffoldModel(
    connection,
    new DatabaseModelFactoryOptions(new []{"dbo.Order", "dbo.User"}, new string[0]),
    new ModelReverseEngineerOptions(),
    new ModelCodeGenerationOptions()
    {
        ContextName = "TestContext",
        ModelNamespace = "TestFiles",
           
    });


model.Display();

var code = @"using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;";

foreach (var file in  new[] { model.ContextFile.Code }.Concat(model.AdditionalFiles.Select(f => f.Code)))
{
    var namespaceToFind = "namespace TestFiles;";
    var headerSize = file.LastIndexOf(namespaceToFind)  + namespaceToFind.Length;
    var fileCode = file
        // remove namespaces, which don't compile in Roslyn scripting
        .Substring(headerSize).Trim();

    code += fileCode;
}

code

AutumnEvans418 avatar Apr 10 '24 18:04 AutumnEvans418