Implementing Code First and Initializing using code

Discussion of open issues, suggestions and bugs regarding Entity Framework support in ADO.NET Data providers
Post Reply
dgxhubbard
Posts: 47
Joined: Fri 14 Aug 2015 20:58

Implementing Code First and Initializing using code

Post by dgxhubbard » Wed 02 Aug 2017 00:16

I have tried to put together a code first example using devart sqlite resources. I want to initialize purely in code. This example has an entity class Student and code to initialize the context as shown below.
When InstancesDbUtilities.DatabaseConnectionString is passed to DbContext string constructor I get the error: "Keyword not supported: 'provider'.", but is I pass the connection name "myContext" as shown in the app.config everything works. I want to keep the app.config with no information except the entity framework reference, what should the connection string look like that InstancesDbUtilities.DatabaseConnectionString returns, and is the configuration and initialization done correctly for code only.

Note: We are a current customer but submitting a ticket showed we were not registered.

Code: Select all


    [Table ( "Students" )]
    public class Student
    {

        [Key]
        [DatabaseGenerated ( DatabaseGeneratedOption.Identity )]
        public int StudentId
        { get; set; }

        [Required]
        public int StudentName
        { get; set; }
}

and the following DbContext, configuration and initializer:

Code: Select all

    public class InstancesInitializer : DropCreateDatabaseAlways<InstancesContext>
    {

        public override void InitializeDatabase ( InstancesContext context )
        {
            if ( context.Database.Exists () )
            {
                if ( !context.Database.CompatibleWithModel ( true ) )
                {
                    context.Database.Delete ();
                }
            }
            context.Database.Create ();
        }

        protected override void Seed ( InstancesContext context )
        {

            base.Seed ( context );
        }
    }


    public class InstancesDbConfiguration : SQLiteEntityProviderServicesConfiguration
    {
        public InstancesDbConfiguration () :
            base ()
        {
            SetProviderFactory ( "Devart.Data.SQLite", SQLiteProviderFactory.Instance );
            SetProviderServices ( "Devart.Data.SQLite.Entity", Devart.Data.SQLite.Entity.SQLiteEntityProviderServices.Instance );
        }

    }

    [DbConfigurationType ( typeof ( InstancesDbConfiguration ) )]
    public class InstancesContext : DbContext
    {

        public InstancesContext () :
            base ( Gt.MultiInstanceController.Utilities.InstancesDbUtilities.DatabaseConnectionString )
        {
            Configure ();
            SetInitializer ();
        }

        public InstancesContext ( DbConnection connection ) :
            base ( connection, true )
        {
            Configure ();
            SetInitializer ();
        }

        private void Configure ()
        {
            Configuration.AutoDetectChangesEnabled = false;
            Configuration.LazyLoadingEnabled = true;
            Configuration.ProxyCreationEnabled = false;
            Configuration.ValidateOnSaveEnabled = true;
        }


        public void SetInitializer ()
        {
            var databasePath = Gt.MultiInstanceController.Utilities.InstancesDbUtilities.DatabasePath;

            Debug.WriteLine ( "InstancesContext.SetInitializer start" );

            if ( !File.Exists ( databasePath ) )
                Debug.WriteLine ( "Database not found " + databasePath );


            /*
                Database.SetInitializer< InstancesContext > ( new CreateDatabaseIfNotExists< InstancesContext > () );
            else
                Database.SetInitializer< InstancesContext > ( new DropCreateDatabaseIfModelChanges< InstancesContext > () );
            */


            Database.SetInitializer<InstancesContext> ( new InstancesInitializer () );


            if ( !Database.Exists () )
            {
                Database.Initialize ( true );
            }

            Debug.WriteLine ( "InstancesContext.SetInitializer end" );
        }


        protected override void OnModelCreating ( DbModelBuilder modelBuilder )
        {

            ///////////////////////////////////////////////////////////////////////
            // ColumnTypeCasingConvention should be removed for dotConnect for Oracle.
            // This option is obligatory only for SqlClient.
            // Turning off ColumnTypeCasingConvention isn't necessary
            // for  dotConnect for MySQL, PostgreSQL, and SQLite.

            //modelBuilder.Conventions
            //  .Remove<System.Data.Entity.ModelConfiguration.Conventions
            //    .ColumnTypeCasingConvention> ();

            ///////////////////////////////////////////////////////////////////////
            // If you don't want to create and use EdmMetadata table
            // for monitoring the correspondence
            // between the current model and table structure
            // created in a database, then turn off IncludeMetadataConvention:
            

            //modelBuilder.Conventions
            //  .Remove<System.Data.Entity.Infrastructure.IncludeMetadataConvention> ();


        }

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

    }

In addition there is a connection string initializer:

Code: Select all


    public static class InstancesDbUtilities
    {
        #region Constants


        public const string DatabaseFile = "Instances" + SQLiteConstants.DatabaseFileExt;

        #endregion


        #region Properties



        public static string DatabasePath
        {
            get
            {
                return Path.Combine ( PathUtilities.AppFiles, DatabaseFile );
            }
        }



        public static string DatabaseConnectionString
        {
            get
            {
                var csb = new SQLiteConnectionStringBuilder ();
                csb.DataSource = Path.Combine ( PathUtilities.AppFilesPath, DatabaseFile );
                csb.FailIfMissing = false;

                var connectionStr = csb.ToString ();

                var ecsb = new System.Data.EntityClient.EntityConnectionStringBuilder ()
                {
                    Provider = "Devart.Data.SQLite",
                    ProviderConnectionString = connectionStr
                };


                connectionStr = ecsb.ToString ();

                return connectionStr;
            }
        }

        #endregion
    }

App.Config

Code: Select all


<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
            <section name="Gt.MultiInstanceController.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
        <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    </configSections>
<!--
    <entityFramework>
        <providers>
            <provider invariantName="Devart.Data.SQLite.Entity" type="Devart.Data.SQLite.Entity.SQLiteEntityProviderServices, Devart.Data.SQLite.Entity, Version=5.3.497.0, Culture=neutral, PublicKeyToken=09af7300eec23701" />
        </providers>
    </entityFramework>
    
    <system.data>
        <DbProviderFactories>
            <remove invariant="Devart.Data.SQLite" />
            <add invariant="Devart.Data.SQLite" type="Devart.Data.SQLite.SQLiteProviderFactory, Devart.Data.SQLite, Version=5.3.497.0, Culture=neutral, PublicKeyToken=09af7300eec23701" />
        </DbProviderFactories>
    </system.data>
-->

    <connectionStrings>
        <add name="myContext" connectionString="Data Source=C:\Repository\GtNext\AppFiles\Instances.db3;FailIfMissing=False" providerName="Devart.Data.SQLite" />
    </connectionStrings>

</configuration>


Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Re: Implementing Code First and Initializing using code

Post by Shalex » Thu 03 Aug 2017 10:46

Your app.config includes outdated versions / names (viewtopic.php?t=33574 > the "Entity Framework Assembly Name Change" section).

Please install dotConnect for SQLite v5.9.946 (control current version via Tools > SQLite > About), open sample from http://blog.devart.com/entity-framework ... ml#Samples, remove projects *DB2, *MySql, *Oracle, *PostgreSql, *SqlServer. Select the project *SQLite and run the Tools > SQLite > Upgrade Wizard to update versions / names.
Also run "install-package entityframework" via Tools > NuGet Package Manager > Package Manager Console to update the EntityFramework package (two times: for CrmDemo.EFCodeFirst and for CrmDemo.EFCodeFirst.dcSQLite). Now it should work.

Post Reply