update Migration Command Fails for ConfigurationDbContext and PersistentGrantDbContext - asp.net-core

I have been trying to get IdentityServer4 version 1.5.2 to work for a few days now without success. I am using VS2017
My Entity classes,DataContexts, repositories and migrations are resident in a .Net Standard Library (1.6). So far so good except when I run update-migration command for "PersistenGrantDbContext" and "ConfigurationDbCOntext". I get the error message
Could not load file or assembly 'System.Data.SqlClient, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
The datacontext classes that i created myself dont seem to have this problem after implementing "IDbContextFactory" interface
Here I have the implementation for the two culprits
public class TemporaryDbContextFactoryScopes : IDbContextFactory<PersistedGrantDbContext>
{
public PersistedGrantDbContext Create(DbContextFactoryOptions options)
{
var builder = new DbContextOptionsBuilder<PersistedGrantDbContext>();
builder.UseSqlServer("Server=-------;Database=-----------;Trusted_Connection=True;MultipleActiveResultSets=true",
optionsBuilder => optionsBuilder.MigrationsAssembly(typeof(UserDbContext).GetTypeInfo().Assembly.GetName().Name));
return new PersistedGrantDbContext(builder.Options, new OperationalStoreOptions());
}
}
public class TemporaryDbContextFactoryOperational : IDbContextFactory<ConfigurationDbContext>
{
public ConfigurationDbContext Create(DbContextFactoryOptions options)
{
var builder = new DbContextOptionsBuilder<ConfigurationDbContext>();
builder.UseSqlServer("Server=---------;Database=--------;Trusted_Connection=True;MultipleActiveResultSets=true",
optionsBuilder => optionsBuilder.MigrationsAssembly(typeof(UserDbContext).GetTypeInfo().Assembly.GetName().Name));
return new ConfigurationDbContext(builder.Options, new ConfigurationStoreOptions());
}
}
I have installed the latest version of System.Data.SqlClient still not working

Just wanted to share what I did to get things rolling. Not sure if that is the right approach though
First I did this in the class library .csproj
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.1" />
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="1.0.1" />
which turned out to be a bad idea because that was throwing out that error now without it running my migrations with my web app as my start up project return the error "Not context blah blah with name blah blah found"
So I realised contexts that I created myself worked without glitches so I did this for PersistentGrantDBCOntext and COnfigurationGrantDbContext
public class PGrantDbContext: PersistedGrantDbContext
{
public PGrantDbContext(DbContextOptions<PersistedGrantDbContext> options, OperationalStoreOptions storeOptions) : base(options, storeOptions)
{
}
}
and
public ConfigDbContext(DbContextOptions<ConfigurationDbContext> options, ConfigurationStoreOptions storeOptions):base(options,storeOptions)
{
}
and everything went smoothly.
Just not so sure if it is the right approach though

I was also in a similar situation few weeks ago and here's how I solved it.
Very similar to yours, I have two projects called Company.Identity (.NETCoreApp) as my Identity Project and Company.Identity.Data (.NETStandard 1.6) for migrations. I Use Company.Identity Project as the startup project for migration purposes as it is in the same solution as my data project and I didn't want to clutter the solution with yet another project just as a startup project for migrations.
I followed the tutorial in here.
The cli tool reference <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.1" /> is in my Company.Identity.csproj file.
I followed all the steps in the above tutorial except for the following difference
In ConfigureServices method in the Company.Identity Startup class, I have set the migrationsAssembly to Company.Identity.Data
var migrationsAssembly = "Company.Identity.Data";
Note that Company.Identity project has already got IdentityServer4.EntityFramework nuget package installed. This enabled me to add the migration for PersistedGrantDbContext. But when I tried to run migration for ConfigurationDbContext it gave me a build error. This was because the migrations generated for PersistedGrantDbContext requried IdentityServer4.EntityFramework nuget package. So I had to install that in the Company.Identity.Data project
I was able to add migrations using the following commands after above changes through command prompt in my Company.Identity project.
dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Migrations/IdentityServer/PersistedGrantDb -p ../Company.Identity.Data
dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Migrations/IdentityServer/ConfigurationDb -p ../Company.Identity.Data
Hope that helps

this may help you specially if you have docker-compose in your project. i was able to resolve this issue by removing the docker-compose project and then creating the migrations then adding it again.
https://stackoverflow.com/a/60320410/4977086

Related

Migrations in separate assembly how to avoid hardcoded connection string?

I'm writing ASP.NET Core and Entity Framework Core application and I want to store my data access layer in separate assembly, so I followed this tutorial: http://www.michael-whelan.net/ef-core-101-migrations-in-separate-assembly/
But I would also like to avoid hardcoding connection string. I tried to store it in JSON config file or as environment variable and get it using ConfigurationBuilder but when using command line migration tool dotnet ef migrations none of these are available.
Is there any way to solve this problem? I'm using 1.0.1 versions of both .NET Core and EF Core.
To solve this issue I create a class library only for migration with a DbContext deriving from my DbContext but with hard connected connection string.
using Microsoft.EntityFrameworkCore;
namespace ChatLe.Repository.Identity.SqlServer
{
public class ChatLeIdentityDbContext: ChatLe.Models.ChatLeIdentityDbContext
{
public ChatLeIdentityDbContext()
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=chatle;Trusted_Connection=True;MultipleActiveResultSets=true");
base.OnConfiguring(optionsBuilder);
}
}
}
Then I launch ef tool command like this :
To add a migration run dotnet ef --startup-project {path to my startup project} migrations add login-activity --context ChatLe.Repository.Identity.SqlServer.ChatLeIdentityDbContext
To upgrade the database run dotnet ef --startup-project {path to my startup project} database update --context ChatLe.Repository.Identity.SqlServer.ChatLeIdentityDbContext
Read the full sample on my git hub project : https://github.com/aguacongas/chatle/tree/develop/src/ChatLe.Repository.Identity.SqlServer

Automatically execute migrations when publishing ASP.NET Core app

Question
Is there any ways that I can automatically execute the migration code (EF 7) when publishing my ASP 5 application to IIS using Web Deploy?
I Tried
in the project.json, I added this code in the scripts:
"scripts" : {
"prepublish": ["dnx ef database update", "other commands..."],
"postpublish": ["dnx ef database update"]
}
none worked for me.
Additional Info
I followed the instructions on this link to deploy my ASP 5 RC-1 web application to IIS using web deploy.
After doing so in the publish settings I have:
Using web deploy in ASP 4 applications I have additional database options:
Use context.Database.Migrate()
You can call this from your Startup class:
using (var context = new MyContext(...))
{
context.Database.Migrate();
}
It will migrate your database to the latest version on application startup. But be careful doing it, maybe comment out this code and uncommend only when you want to run your migrations.
Apparently this process does not work now. https://github.com/aspnet/Home/issues/622 After you publish you should find the power shell script with the name of "profile name"-publish.ps1. Then add your commands below these three lines close to the end of this file. You might want to use powershell to make it easier to debug.
'Calling Publish-AspNet' | Write-Verbose
# call Publish-AspNet to perform the publish operation
Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput
So I added the option -environment to my ef database command. Now it works:
"postpublish": ["dnx ef database update -e Staging"]
I have four different appsettings.json which different connection string for each environment. Just needed to indicate the environment for the command to work.
In you Startup.cs class add this code
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<AppDBContext>();
context.Database.Migrate();
}
}

EF6 localdb for integration testing

I am developing a WPF application which requires some database access. For development purposes I am using localdb with database migrations enabled and EF6.
What I cannot figure out is how do I configure a separate localdb database for integration tests inside a VS2013 test project and run the database migrations to bring it up to date and then seed it with data.
Here's what I've ended up doing based off information from several sources. First, in the App.Config of my test project I've added the following
<connectionStrings>
<add name="YourContextName" connectionString="Data Source=(localdb)\mssqllocaldb;Integrated Security=true;AttachDBFilename=|DataDirectory|\databasename.mdf"
providerName="System.Data.SqlClient" />
</connectionStrings>
Then I created the following class:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Data.Entity;
using MyProject.Model.Entities;
using MyProject.Migrations;
namespace IntegrationTests
{
public class DatabaseInitializer : DropCreateDatabaseAlways<MyProjectDataContext>
{
}
[TestClass]
public class Initalize
{
[AssemblyInitialize]
public static void AssemblyInit(TestContext context)
{
AppDomain.CurrentDomain.SetData("DataDirectory", context.TestDeploymentDir);
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyProjectDataContext, Configuration>());
//Database.SetInitializer(new DatabaseInitializer());
}
}
}
My understanding is that this runs before each test run. The SetData call updates the |DataDirectory| used in the App.Config so that it is unique and doesn't try to use the same instance as the normal project.
From there I have the choice of either running the migrations and then supplying some test data as part of the test or to run an initializer that sets up the test data. Note that to run the migrations the configuration class generated by the migration must be changed from internal to public.
This seems to work so far. Not sure if this is the best way or if I can combine the migrations and then run a different seed for the tests.
Within your test project, you could set Database.SetInitializer() (or databaseInitializer within the project config file) with MigrateDatabaseToLatestVersion or with your own IDatabaseInitializer that calls DbMigrator.Update, and use a custom DbMigrationsConfiguration.
The test project could use a separate connection string for using LocalDB, and if the file referenced by your connection string's AttachDBFilename, then the initializer will try to create it.
Might be helpful: Recreate and Reseed LocalDb Before Each Unit Test
...But DropCreateDatabaseAlways won't work with EF6 migrations

VS2012 Entity Framework Error

I have a MCV 4.5 solution with 3 projects. Site, Testing and Model. Site and Model are referencing EF 5.0. I have searched all solution files for a reference to 4.3.1 and have come up empty. I have deleted and recreated all references to EF 5.0
I have a HomeControllerTest.cs that runs just fine.
using this as a test
[TestMethod]
public void Index()
{
// Arrange
HomeController controller = new HomeController();
// Act
ViewResult result = controller.Index() as ViewResult;
// Assert
Assert.AreEqual("Modify this template to jump-start your ASP.NET MVC application.", result.ViewBag.Message);
}
I Created a new LOBControllerTest.cs to support the LOBController.cs in the Site Project. This test class fails with the error 'Could not load file or assembly 'EntityFramework, Version=4.3.1.0' using the following test
[TestMethod]
public void Index()
{
// Arrange
LOBController controller = new LOBController();
// Act
ViewResult result = controller.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
}
If I change the above test to execute the HomeController as in the following, it runs just fine.
[TestMethod]
public void Index()
{
// Arrange
HomeController controller = new HomeController();
// Act
ViewResult result = controller.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
}
This is a brand new clean install of VS2012 on a clean install of Windows Server 2012.
Any Thoughts?
Update, I forgot to mention I am also using ReSharper 7.1. I'm wondering if that has a setting that I was missing.
I found that there is a documented bug with RS7 stackoverflow.com/questions/12357696/… so I disabled the RS7 testing suite and tried running it directly from VS2012 interface with the same result. So it's not isolated to RS7.
Update:
here's a link https://www.dropbox.com/sh/740w2jsp8i1mslg/pWiwnSewHQ to access this project for anyone who want's to take a look at it. It's nothing special it's just a Template project. We are starting on a new project at work and I'm new to MVC and Test Driven Development so I'm trying to get a head start.
Update 9/21/2012
I believe I've found it. After talking to the Dev who put the original Wholesale template solution together I found that the Repositories folder in the Wholesale.Admin is references a NUGet code package. I checked the package site and found that the latest release is dependent on EF 4.3.1
Update:
This is confirmed. I no longer get the error after downloading and upgrading the solution from the site. I get another error but the 4.3.1 is no longer an issue. Hope the dev will update his NuGet solution, he hasn't updated it in 7 months.
Obviously your LOBController references EF 4.3 somehow, somewhere. Check your references in the class library containing this controller, or maybe a dll that's still in the bin folder or in the GAC...
Hope this helps
After talking to the Dev who put the original Wholesale template solution together I found that the Repositories folder in the Wholesale.Admin references a NUGet code package. I checked the package site and found that the latest release is dependent on EF 4.3.1. I downloaded the source and recompiled referencing EF 5.0 and that cleared the 4.3.1 error

Getting Fluent NHibernate to work with SQLite

I'm sure there is something simple I've not done but I'm trying to get Fluent NHibernate to work with Sqlite on my machine.
I used NuGet to download fluent nhibernate and added the following entity and mapping:
public class Customer
{
public virtual string CustomerCode { get; set; }
public virtual string Name { get; set; }
}
public class CustomerMap : ClassMap<Customer>
{
public CustomerMap ()
{
Id(x => x.CustomerCode);
Map(x => x.Name);
Table("tblCustomer");
}
}
Then following the getting started with fluent guide I added the following code to a Windows Command project:
class Program
{
static void Main(string[] args)
{
var sessionFactory = CreateSessionFactory();
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var customer = new Customer { CustomerCode = "123", Name = "Bob" };
session.SaveOrUpdate(customer);
transaction.Commit();
}
}
}
private static ISessionFactory CreateSessionFactory()
{
return Fluently.Configure()
.Database(
SQLiteConfiguration.Standard
.UsingFile("firstProject.db")
)
.Mappings(m =>
m.FluentMappings.AddFromAssemblyOf<Program>())
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
private static void BuildSchema(Configuration config)
{
// delete the existing db on each run
if (File.Exists("firstProject.db"))
File.Delete("firstProject.db");
// this NHibernate tool takes a configuration (with mapping info in)
// and exports a database schema from it
new SchemaExport(config)
.Create(false, true);
}
}
Finally I added the Sqlite dll using NuGet.. however I'm getting the following error when trying to run the program:
Top Exception:
An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
Next Exception:
Could not create the driver from NHibernate.Driver.SQLite20Driver, NHibernate, Version=3.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4.
Inner most exception:
Unable to find the requested .Net Framework Data Provider. It may not be installed.
This is when it's trying to create the session factory.
Can anyone help with this? I'm running a 32 bit machine?
Thanks
Dave
You need two things:
Reference System.Data.SQLite in your project.
Include sqlite3.dll, but you also can’t add reference to sqlite3.dll, because it’s an unmanaged dll. Simply add it as element to solution and set it to copy to output directory.
You need the .NET provider for Sqlite. Download it here http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki
After initial investigation I thought it was because my System.Data.SQLite assembly wasn't loaded into memory at the time, so I included code to preload the system.Data.SQLite assembly. However when running the application the real error arose:
Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.
to fix this I changed my app.config to look like the following:
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
with the important bit being useLegacyV2RuntimeActivationPolicy="true"
I was having the same problem today, and spend an hour searching for a solution. Anyway, I found one here:
http://thelongwayback.wordpress.com/2009/11/02/fluent-nhibernate-sqlite-problem-the-idbcommand-and-idbconnection-implementation-in-the-assembly-system-data-sqlite-could-not-be-found/
Basically, you'll have to use an older version of SQLite (v1.0.60) from here:
http://sourceforge.net/projects/sqlite-dotnet2/files/
On another note, I got the same code working yesterday on a machine with VS2010 SP1. The same code wouldn't run today on a machine without SP1. If anyone gets a chance to test this one, i.e., by installing VS2010 SP1, let me know the outcome please.
None of the above solutions, or any else I could find on the Internet, worked for me... until...
I had to install both the x64 and x86 versions of SQLite (per Vadim's link: http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki), specifically in that order.
Initially, I installed the 32-bit before the 64-bit version, which did not fix anything. On a whim, I uninstalled them both and reinstalled them in the opposite order. Now it works!
I've tested this on 2 different machines and verified this was the fix for both of them. Wacky, but effective.
I also encountered this problem.
Noticed that the starter sample project targets .net framework 3.5 and the one I created (exercise project) is targeting .net framework 4.0 client profile (default of vs2010).
I changed the target version to 3.5 and I was able to work on my exercise project.
In my case it worked to install the System.Data.SqLite via NuGet.
So I opened the "Tools/NuGet Package Manager/Package Manager console" and typed:
Install-Package System.Data.SqLite