locked
Making EF Core properties backward compatible with Linq-To-Sql RRS feed

  • Question

  • User-1262787652 posted

    ASP. NET MVC 4.8 application uses DbLinq. 

    Database has tables where column and table names are same:


    CREATE TABLE Product ( Product CHAR(20) PRIMARY KEY ); Sql to Linq created entites with Contents property from them: public class Product ( public string Contents { get; set; } } Contents propery becomes part of published API used by third-party applications. EF Core scaffold creates property Product1 instead: public class Product ( public string Product1 { get; set; } }

    This breaks API specification. How to make EF Core with API compatible ?

    Is it possible to force it to generate Contents property as Sql to Linq ?

    Or is it possible to add additional Contents property which actually gets and sets Product1 property values ?

    Npgsql EF Core provider is used in ASP.NET Core MVC application.

    Sunday, February 7, 2021 2:27 PM

Answers

  • User-821857111 posted

    I don't believe the scaffolding tool that ships with EF Core is designed to be automated continuously. You probably need to write your own scaffolding tool. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, February 9, 2021 7:44 PM
  • User-1262787652 posted

    Hi!

    I'm using https://github.com/jdtcn/RuntimeEfCore

    I have tested in Debian Linux and seems that it works well. Scaffold + compile takes 10 seconds. Result assembly is written to application directory replacing original datacontext assembly. This allows sync DbContext with database structure changes.

    It is wrapper to EF Scaffold. 

    I'm using

    static IReverseEngineerScaffolder CreatePostgreScaffolder()
            {
                return new ServiceCollection()
                    .AddEntityFrameworkNpgsql()
                    .AddLogging()
                    .AddEntityFrameworkDesignTimeServices()
                    .AddSingleton<LoggingDefinitions, NpgsqlLoggingDefinitions>()
                    .AddSingleton<IRelationalTypeMappingSource, NpgsqlTypeMappingSource>()
                    //.AddSingleton<IAnnotationCodeGenerator, AnnotationCodeGenerator>()
                    .AddSingleton<IDatabaseModelFactory, NpgsqlDatabaseModelFactory>()
                    .AddSingleton<IProviderConfigurationCodeGenerator, NpgsqlCodeGenerator>()
                    .AddSingleton<IScaffoldingModelFactory, RelationalScaffoldingModelFactory>()
                    .AddSingleton<IPluralizer, HumanizerPluralizer>()
                    .BuildServiceProvider()
                    .GetRequiredService<IReverseEngineerScaffolder>();
            }
    
    

    Maybe it is possible to replace some middleware here with custom one which creates property name Contents  if table and column names are same.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, February 9, 2021 8:20 PM

All replies

  • User-821857111 posted

    kobruleht

    How to make EF Core with API compatible ?

    Change the name of the scaffolded property to "Contents" and then map it to the "Product" column using either an attribute or the fluent API:

    Column attribute: https://www.learnentityframeworkcore.com/configuration/data-annotation-attributes/column-attribute

    public class Product (
        [Column("Product")]
           public string Contents { get; set; }  
           }

    Fluent API To Column: https://www.learnentityframeworkcore.com/configuration/fluent-api/hascolumnname-method

    modelBuilder.Entity<Product>()
                .Property(b => b.Contents).HasColumnName("Product");

    I recommend using the Fluent API because it supports more configuration than attributes.

    https://www.learnentityframeworkcore.com/configuration/fluent-api

    Once you have added your own configuration, use migrations to keep the schema in sync with the model. In EF Core, scaffolding is only intended to be used once per project.

    https://www.learnentityframeworkcore.com/migrations

    Monday, February 8, 2021 5:08 AM
  • User-1262787652 posted

    Change the name of the scaffolded property to "Contents" and then map it to the "Product" column using either an attribute or the fluent API:

    Scaffolding is done continuously in runtime. How to automate this so that this is scaffolded automatically ?

    Once you have added your own configuration, use migrations to keep the schema in sync with the model. In EF Core, scaffolding is only intended to be used once per project.

    Link you provided and MS documentation define migration like applying  C# model source code changes to database. In my case database is changed outside of C# application. Database changes needs migrated to EF Core model. This is not supported in EF Core.

    So continuous scaffold with re-create whole model after every change must used.

    Tuesday, February 9, 2021 6:08 PM
  • User-821857111 posted

    I don't believe the scaffolding tool that ships with EF Core is designed to be automated continuously. You probably need to write your own scaffolding tool. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, February 9, 2021 7:44 PM
  • User-1262787652 posted

    Hi!

    I'm using https://github.com/jdtcn/RuntimeEfCore

    I have tested in Debian Linux and seems that it works well. Scaffold + compile takes 10 seconds. Result assembly is written to application directory replacing original datacontext assembly. This allows sync DbContext with database structure changes.

    It is wrapper to EF Scaffold. 

    I'm using

    static IReverseEngineerScaffolder CreatePostgreScaffolder()
            {
                return new ServiceCollection()
                    .AddEntityFrameworkNpgsql()
                    .AddLogging()
                    .AddEntityFrameworkDesignTimeServices()
                    .AddSingleton<LoggingDefinitions, NpgsqlLoggingDefinitions>()
                    .AddSingleton<IRelationalTypeMappingSource, NpgsqlTypeMappingSource>()
                    //.AddSingleton<IAnnotationCodeGenerator, AnnotationCodeGenerator>()
                    .AddSingleton<IDatabaseModelFactory, NpgsqlDatabaseModelFactory>()
                    .AddSingleton<IProviderConfigurationCodeGenerator, NpgsqlCodeGenerator>()
                    .AddSingleton<IScaffoldingModelFactory, RelationalScaffoldingModelFactory>()
                    .AddSingleton<IPluralizer, HumanizerPluralizer>()
                    .BuildServiceProvider()
                    .GetRequiredService<IReverseEngineerScaffolder>();
            }
    
    

    Maybe it is possible to replace some middleware here with custom one which creates property name Contents  if table and column names are same.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, February 9, 2021 8:20 PM