Get-DbContext returns unusable database contexts - sql-server

Similar questions are:
More than one DbContext was found - answers mainly discuss syntax
Unable to create an object of type 'ApplicationDbContext'. For the different patterns supported at design time - nothing here
After a year away from this project I decided to change some database fields. So I have now remodelled the database schema for my ASP .Net Entity Frameworks (with Identity) project. My changes have remodelled my data table NOT the identity part of my project.
Get-Package
Id Versions ProjectName
-- -------- -----------
bootstrap {5.1.0} rollbase
Microsoft.EntityFrameworkCore.Sq... {5.0.12} rollbase
Microsoft.EntityFrameworkCore.De... {5.0.11} rollbase
Microsoft.AspNetCore.Diagnostics... {5.0.9} rollbase
Microsoft.AspNetCore.Identity.En... {5.0.9} rollbase
Microsoft.EntityFrameworkCore.Tools {5.0.11} rollbase
Microsoft.VisualStudio.Web.CodeG... {5.0.2} rollbase
Microsoft.AspNetCore.Identity.UI {5.0.12} rollbase
I decided to remove my migrations folder, to begin again, because I already had a lot of migrations. I checked on what database contexts I have:
PM> Get-DbContext
Build started...
Build succeeded.
The Entity Framework tools version '5.0.11' is older than that of the runtime '5.0.12'. Update the tools for the latest features and bug fixes.
ApplicationDbContext
rollbase.Areas.Identity.Data.ApplicationDbContext:
For:
PM> Add-Migration InitialCreate -Verbose
I get this familiar error:
More than one DbContext was found. Specify which one to use. etc
Using the output of Get-DbContext I try:
PM> Add-Migration InitialCreate -Context ApplicationDbContext
Even though I specify the context I still get the 'More than one DbContext was found'
Using:
PM> Add-Migration InitialCreate -Context IdentityDbContext -Verbose
I get: No DbContext named 'IdentityDbContext' was found.
Recapping on what I know about my database context:
The database context is registered with the Dependency Injection container in the ConfigureServices method in Startup.cs file:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
Here. Just like the output from Get-DbContext It is clear that the DbContext to be used is ApplicationDbContext
However. After reading This DbContext Lifetime, Configuration, and Initialization the following caught my attention:
"The ApplicationDbContext class must expose a public constructor with a DbContextOptions<ApplicationDbContext> parameter. This is how context configuration from AddDbContext is passed to the DbContext. For example:"
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
But my ApplicationDbContext class looks like this:
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
So my ApplicationDbContext inherits from IdentityDbContext instead of DbContext?
I found this old stackoverflow post ASP.NET Identity DbContext confusion which discusses the same problem. I must confess I got lost reading the proposals for dealing with this issue. Partly due to the fact that I have a solution that I've had running fine. Deployed to Azure etc.
The last migration shows on GitHub repo like this:
namespace rollbase.Data.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20211015203803_UpdateIncludeEntryTable")]
At this point I'm confused. I had previously done around 10 migrations on this project. I can still log in as a user. So why can't I choose a database context and migrate my remodeling to localdb?
Any suggestions would be appreciated.

The answer was quite simple. The beginning of this doc Design-time DbContext Creation illustrates the call chain for getting DbContext
Looking at Visual Studio Solution Explorer. It was easy to follow the path:
So the correct command was:
PM> Add-Migration InitialCreate -Context rollbase.Data.ApplicationDbContext
It seems ridiculously easy now.

Related

dotnet ef database update on ASP.NETCORE2.1 project with MSSQLSERVER - Format of the initialization string does not conform to specification ..index 0

As the title says, I am trying to use dotnet ef database update from the command line and getting the error Format of the initialization string does not conform to specification starting at index 0.
From searching around this site and the internet, everything points to the connection string being wrong, but the connection string is working fine to compile and run the application. I am trying to add Identity to the project so I can have users with passwords, and am trying to follow the Deep Dive tutorial on pluralsight, but when it gets to this part, the code fails.
My connection string in appsettings.json is
"ConnectionStrings": {
"DefaultConnection": "Server=PTI-VWS12-002;Database=EPDM_TestVault;Trusted_Connection=true;MultipleActiveResultSets=true;"
},
The code in my Startup.cs is:
var migrationAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), sql=> sql.MigrationsAssembly(migrationAssembly)));
though i've also tried it without the migration assembly as well. I'm really not sure what could be wrong with my connection string.
EDIT: My constructor:
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration) { Configuration = configuration; }
And my constructor has the default for ASP.NET CORE 2.1
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>();
EDIT 2: Solved.
I'm still not sure what I did wrong in my project, but i got the Identity tables to generate using the official Asp.NET sample project library over here https://github.com/aspnet/Docs. Using the exact migration file from the IdentityDemo, and plopping in my connection string from above, I was able to create the Identity tables in my database.
You first need to configure IConfiguration using IConfigurationBuilder in Constructor of startup or in Program.cs before Kestrel Server startup.
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
_configuration = builder.Build();
I'm still not sure what I did wrong in my project, but i got the Identity tables to generate using the official Asp.NET sample project library over here https://github.com/aspnet/Docs. Using the exact migration file from the IdentityDemo, and plopping in my connection string from above, I was able to create the Identity tables in my database.
EDIT: it still doesn't run in context of my program.

Dapper: Cannot read/map Geometry type field in local SQL Server

I am running ASP.NET Core 2 application.
I have a local instance of SQL Server where I have a table with a column of type Geometry.
When I go to read this table I get the following errors:
Type Udt is not supported on this platform.
Error parsing column 4 (MyLocation)
However this issue only seems to occur in my API project which calls to a custom made Nuget package that handles the CRUD operations.
If I test the same code in the project that does the CRUD it reads and maps my object.
It is not a connection issue in the API for I can successfully read/write other tables that do not have a Geometry field in it.
What could I possible be missing?
Code:
MyController:
public async Task<IActionResult> Get(Guid Id)
{
var rec = await myRepo.Get<MyData>(id);
// then do stuff
}
*myRepo is injected into my controller.
public class MyData
{
public Guid Id {get;set;}
public IGeometry MyLocation {get;set;}
}
myRepo:
public async Task<TEntity> Get<TEntity>(object id)
where TEntity : class
{
_conn.Open();
return await _conn.GetAsync<TEntity>(id);
}
If this is .NET Core, then I suspect you could have significant issues using sqlgeography etc; UDTs essentially aren't yet implemented in .NET Core:
Additionally, the underlying types that you would want to load use native code; the geo/etc types are not, AFAIK, available in .NET Core.
If I'm wrong, I'm more than happy to try to make whatever changes we need to help make this work, but at the time of writing: I don't think this is going to work through any API (it is not specific to Dapper).
You might want to consider using ASP.NET Core on .NET Framework for today? reference .Net framework 4.5.2 from .Net Core 2.0 project
If this data does actually load from ADO.NET in .NET Core, then I'd be happy to fix whatever I've missed.

Read connection string from app.config in my DataAccess library project for dbContext

I am working on a VS2012 solution that has got an ASP.NET MVC 4.0 project and multiple class libraries like my Managers, providers and DataAccess projects. My dbContext class is defined inside the DataAccess project.
My aim is to restrict the connection string info in the DataAccess project's App.Config file. I am trying to avoid specifying the connectionString anywhere else in the project as it is my DataAccess classes that would interact with the DB.
Now if I specify my connection string the my dbContext class by hard coding it, my project works fine and is able to read data from DB.
public MyDbContext()
: base(#"Data Source=MYLAPTOP\SQL2012MAIN;Initial Catalog=MyDB;User ID=sa;Password=*****")
{
}
But if I specify the connection string in app.config file like this:
<connectionStrings>
<add name="MyDBConnection" connectionString="Data Source=MYLAPTOP\SQL2012MAIN;Initial Catalog=MyDB;User ID=sa;Password=*****;Connect Timeout=200; pooling='true" providerName="System.Data.SqlClient" />
</connectionStrings>
and use it in my dbContext classs as follows:
public MyDbContext()
: base("MyDBConnection")
{
}
It doesn't work. I tried using the same connection string in my MVC project's web.config file also, but then again I am getting the same error (attached image):
Can anybody please guide me...
Thanks Hari
I think your fault lies at the pooling, so try
Pooling=True also make sure to remove the single inverted comma that you have, '
There is one more point you might want to research on, I think that Pooling is by default enabled, so setting Pooling=True, while this is explicit, if I remember correctly, it has no effect, whereas Pooling=False does have a effect.
To make it work you can try calling the base constructor like this:
public MyDbContext()
: base("MyDBConnection", backend, metadataSource)
{
}
In this case, backend and metadataSource would be the fields in your MyDbContext class, which hold the configuration of the backend and the configuration of the mapping.
In the Creating OpenAccessContext article, you will find more details about the design of the context.

Grails 2.1.4 - Database Migration - Error on dbm-gorm-diff

I need to change my database. For this I installed the Database Migration Plugin.
plugins {
…
runtime ':database-migration:1.3.2'
}
I found a tutorial about the usage of this plugin.
My steps are:
grails dbm-generate-changelog changelog.groovy
grails dbm-changelog-sync
After these two steps I changed one Domain class from:
class Event {
...
Date lastAccessed
}
to:
class Event {
...
Date dateCreated
Date lastUpdated
}
According to the tutorial and documentation I need to run now:
grails dbm-gorm-diff
I did this
grails dbm-gorm-diff add-timestamps-to-event.groovy --add
On this part I'm getting the error.
Stacktrace:
| Starting dbm-gorm-diff
12:38:20,561 - ERROR - org.codehaus.groovy.grails.plugins.DefaultGrailsPlugin - Error configuration scaffolding: Error creating bean with name 'instanceControllersApi': Singleton bean creation not allowed while the singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'instanceControllersApi': Singleton bean creation not allowed while the singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
at java.lang.Thread.run(Thread.java:722)
I have no idea where this comes from.
Thanks very much for any suggestions.

How to populate data models with default data in Liferay?

I'm developing a portlet that is deployed as WAR. Database models are created by service builder. How can I insert initial data models to the database when the WAR is installed?
Add to the project a portal.properties file with the property:
application.startup.events=com.my.project.MyStartupAction
and impliment the startup import as extension of SimpleAction:
package com.my.project;
import com.liferay.portal.kernel.events.ActionException;
import com.liferay.portal.kernel.events.SimpleAction;
public class MyStartupAction extends SimpleAction {
#Override
public void run(String[] arg0) throws ActionException {
if(startupDataNotExist()) {
createStartupData();
}
}
...
You can do this either as StartupAction, executed on startup of the plugin (read: during deployment AND during subsequent server starts) or as an UpgradeAction.
A good example for this is the sevencogs-hook that comes with Liferay CE and has the source code included. This is implemented as an UpgradeAction - e.g. on first start your database content will be "upgraded" to contain the sevencogs sample data.
Also you can do it with UpgradingProcess. Here are step-by-step instructions

Resources