EF Core Power Tools EntityFrameworkCore.Design.OperationException suddenly occurring on "Add DbContext Diagram" - entity-framework-core

I've been using EF Core Power Tools to assist with learning EF Core. The data project is simply a class library that contains the base DbContext used by the associated web app, plus the migrations folder.
It's been working fine until suddenly this error occurs when I "Add DbContext Diagram"
System.InvalidOperationException: Error:
Microsoft.EntityFrameworkCore.Design.OperationException: Unable to create an object of type 'EventFinderContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
---> System.InvalidOperationException: Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[EventFinderData.EventFinderContext]' while attempting to activate 'EventFinderData.EventFinderContext'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance(IServiceProvider provider, Type type)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass21_4.<FindContextTypes>b__13()
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.<>c__DisplayClass21_4.<FindContextTypes>b__13()
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
at Modelling.EfCoreModelBuilder.BuildResult(String outputPath, String startupOutputPath, Boolean generateDdl) in C:\Code\EFCorePowerTools\src\GUI\efpt30.core\EFCoreModelBuilder.cs:line 41
at Modelling.Program.Main(String[] args) in C:\Code\EFCorePowerTools\src\GUI\efpt30.core\Program.cs:line 56
at async Task EFCorePowerTools.Handlers.ModelAnalyzerHandler.GenerateAsync(string outputPath, Project project, GenerationType generationType)
I'm not sure even where to start looking to investigate, so any pointers would be appreciated please. The solution builds okay, the database seems fine, and the associated Blazor project also runs fine.
Not sure if its helpful but in my data project, the constructor for the DbContext is this:
namespace EventFinderData
{
public class EventFinderContext : DbContext
{
public EventFinderContext(DbContextOptions<EventFinderContext> options) : base(options)
{
}
}
}

You have to register EventFinderContext in program.cs
builder.Services.AddDbContext<EventFinderContext>(
opt => opt.UseSqlServer("Your_connection_string"));

As advised by ErikEJ (the author of Power Tools) the diagram function only works on the executable project. Once I had added a web application project to my solution, the original console and data layer projects in that solution no longer worked for creating the diagram.

Related

Add-Migration doesn't work after upgrading from Entity Framework Core 1.1 to 2

I upgraded my ASP.NET project from Entity Framework Core 1.1. to Entity Framework Core 2.
I have a class library that targets the .net framework.
I have multiple DBContext in my class library
When I run the command Add-Migration MyMigration I get
More than one DbContext was found. Specify which one to use. Use the '-Context' parameter for PowerShell commands and the '--context' parameter for dotnet commands.
I then run Add-Migration MyMigration -Context MyContext
I then get
Unable to create an object of type 'MyContext'. Add an implementation of 'IDesignTimeDbContextFactory' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
This command use to work
It seems like your upgrade not only Ef,but also Asp.Net CORE. Change your Program.cs file to:
public class Program
{
public static void Main(string[] args)
{
var host = BuildWebHost(args);
host.Run();
}
// Tools will use this to get application services
public static IWebHost BuildWebHost(string[] args) =>
new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
}

UnknownServiceException: Unknown service requested [EnversService]

I want to run Hibernate in OSGi. I have added the standard Hibernate OSGi bundle and a Blueprint implementation, so that Envers gets registered right on startup.
Even without any kind of documentation I found out you have to start Envers, because... I doubt there is a logical reason, it does not work otherwise.
However now, even though Envers was registered in Blueprint, I get the following exception:
org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.envers.boot.internal.EnversService]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:184)
at org.hibernate.envers.boot.internal.TypeContributorImpl.contribute(TypeContributorImpl.java:22)
at org.hibernate.boot.internal.MetadataBuilderImpl.applyTypes(MetadataBuilderImpl.java:280)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.populate(EntityManagerFactoryBuilderImpl.java:798)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:187)
at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:34)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilder(HibernatePersistenceProvider.java:165)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilderOrNull(HibernatePersistenceProvider.java:114)
at org.hibernate.osgi.OsgiPersistenceProvider.createEntityManagerFactory(OsgiPersistenceProvider.java:78)
at org.acme.project.Main.startSession(PersistenceUnitJpaProvider.java:38)
The stack trace starts at PersistenceProvider#createEntityManagerFactory in the following snippet:
public class Main {
private EntityManagerFactory entityManagerFactory;
public void startSession(Map<String, Object> config) {
BundleContext context = FrameworkUtil.getBundle(getClass()).getBundleContext();
ServiceReference<PersistenceProvider> serviceReference = context.getServiceReference(PersistenceProvider.class);
PersistenceProvider persistenceProvider = context.getService(serviceReference);
this.entityManagerFactory = persistenceProvider.createEntityManagerFactory("persistenceUnit", config);
context.ungetService(serviceReference);
}
I found this bug, and maybe this issue is fixed in the current version of Hibernate. But since the bundle IDs are broken, I have to use 5.1.
So Envers is registered, but not really. What could be the reason for such a strange error message?

Entity Framework 6 connection string with DNX

As far as I understand Entity Framework 6, it magically materializes a connection string from app.config/web.config. From DbContext documentation, section remarks:
If the parameterless DbContext constructor is called from a derived context, then the name of the derived context is used to find a connection string in the app.config or web.config file
for the case of the parameterless constructor, or for the case with a connection string name:
Instead of using the derived context name, the connection/database name can also be specified explicitly by passing the name to one of the DbContext constructors that takes a string. The name can also be passed in the form "name=myname", in which case the name must be found in the config file or an exception will be thrown.
However, in a DNX project, I don't have an app.config or web.config. How do I specify a connection in Entity Framework 6 in a DNX project?
there is no need for app.config or web.config at least for code first approach. Connection string can be defined in any configuration file or even without it - hard coded (this is not a good practice).
In ASP.NET 5 with EF6 connection string can be specified in config.json file as usual. This of course assumes loading configuration from json file as #Martijn noticed:
Add two packages to project.json:
"dependencies": {
"Microsoft.Framework.Configuration.Abstractions": "1.0.0-beta8",
"Microsoft.Framework.Configuration.Json": "1.0.0-beta8"
}
Add config.json to your project:
{
"Data": {
"DefaultConnection": {
"ConnectionString": "Data Source=(local);Database=EfExample;Integrated Security=True"
}
}
}
Load config in Program.cs (this class may not be valid after beta8):
[...CODE ...]
using Microsoft.Framework.Configuration;
[...CODE ...]
public class Program
{
public void Main(string[] args)
{
var builder = new ConfigurationBuilder()
.SetBasePath(".")
.AddJsonFile("config.json");
[... CODE ...]
Now DbContext can be created with
new ApplicationDbContext(Configuration["Data:DefaultConnection:ConnectionString"])
Assuming you already have constructor for ApplicationDbContext like this
public ApplicationDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
If you want to know more about configuration in DNX I have blog post about it at: http://bleedingnedge.com/2015/10/15/configuration-providers/
Additional info on different configuration issues with ASP.NET 5 and EF6 can be found here (mostly focused on MVC project though) including configuration for mssql, localdb, postgresql and avoiding other app.config issues: http://bleedingnedge.com/2015/11/01/entity-framework-6-with-asp-net-5/

EF Power Tools Beta 2 - exception has been thrown by the target of an invocation

I have EF 5.0 code-first VS 2012 project and all Entity Framework menu commands (View Entity Data Model DDL SQL) produce "Exception has been thrown by the target of an invocation" popup. I think what has also changed is that EF Power Tools Beta 1 (or VS 2010, I am not sure) use to display EF Power Tools messages in the output window. Now all I get is the popup... Is this VS or Power Tools issue?
this is my work around:
Comment the constructor out, and leave the static MyDbContext as is -->
public class MyDbContext: DbContext
{
public static string ConnectionName = "Name = SMS_ADvTECHContext";
static MyDbContext()
{
Database.SetInitializer<SMS_ADvTECHContext>(null);
}
/* public SMS_MyDbContext()
: base(ConnectionName)
{
}*/
}
Then if you right click the context class --> Enityframework --> View Entity Data Model (read-only) it generate the view!
I ran into this error when I didn't have the correct default connection factory configured in the App.config inside the project that included my DbContext class. I updated it to use the correct factory and this error went away. In my case I set it to use the LocalDbConnectionFactory:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
In ran into this error and it was an even simpler issue ... the project that contained my Context was not the Startup Project. Once I set the project to be the Startup Project it started working.
Maybe Visual Studio is having trouble figuring out what connection string to use for your DBContext, when you choose the Entity Framework menu commands.
In my case, I was able to resolve this by verifying that I had a "default" connection string for my dbContext. So that, when you right click on db context and choose Entity framework, you will have a connection to the DB.
In other words, I had modified my DBContext to select the connection string from a command line parameter to my app. So, normally, my db context did not have a "default" value.
public class MyDbContext : DbContext
{
public static string ConnectionName;
public DnnDbContext()
: base( "Name=" + ConnectionName) {
}
As you can see, I had no ConnectionString by default.
I changed to:
public static string ConnectionName = "DefaultConnNameInAppConfig";
I ran into this when I had multiple connection strings with the same name configured in my web.config.

Code-First Entity Framework - error creating SQL CE DB

I have been using Entity Framework CTP with Code-First as in this tutorial by Scott Guthrie and another by Scott Hanselman (can't post the link, but google "Simple Code First with Entity Framework 4 - Magic Unicorn Feature CTP 4"). This is working perfectly for the main MVC application, but I am now trying to add a testing project, that uses a separate SQL CE Database.
I have added the following to the App.Config file:
<connectionStrings>
<add name="MyData"
connectionString="Data Source=D:\myProject\myDb.sdf;"
providerName="System.Data.SqlServerCe.4.0" />
</connectionStrings>
However when I try to run the tests it throws the following error when trying to create the database:
Test method
MyProjet.Tests.Administration.ModlelTests.Business.TestGetBusinessesList
threw exception:
System.Reflection.TargetInvocationException:
Exception has been thrown by the
target of an invocation. --->
System.TypeInitializationException:
The type initializer for
'System.Data.SqlServerCe.SqlCeProviderServices'
threw an exception. --->
System.Security.VerificationException:
Operation could destabilize the
runtime.
With the following stack trace:
System.Data.SqlServerCe.SqlCeProviderServices..ctor()
System.Data.SqlServerCe.SqlCeProviderServices..cctor()
System.RuntimeFieldHandle.GetValue(RtFieldInfo
field, Object instance, RuntimeType
fieldType, RuntimeType declaringType,
Boolean& domainInitialized)
System.Reflection.RtFieldInfo.InternalGetValue(Object
obj, Boolean doVisibilityCheck,
Boolean doCheckConsistency)
System.Reflection.RtFieldInfo.InternalGetValue(Object
obj, Boolean doVisibilityCheck)
System.Reflection.RtFieldInfo.GetValue(Object
obj)
System.Data.SqlServerCe.ExtensionMethods.SystemDataSqlServerCeSqlCeProviderServices_Instance_GetValue()
System.Data.SqlServerCe.ExtensionMethods.SystemDataSqlServerCeSqlCeProviderServices_Instance()
System.Data.SqlServerCe.SqlCeProviderFactory.System.IServiceProvider.GetService(Type
serviceType)
System.Data.Common.DbProviderServices.GetProviderServices(DbProviderFactory
factory)
System.Data.Common.DbProviderServices.GetProviderServices(DbConnection
connection)
System.Data.Entity.ModelConfiguration.Internal.Configuration.CodeFirstCachedMetadataWorkspace.GetMetadataWorkspace(DbConnection
storeConnection)
System.Data.Entity.Infrastructure.DbModel.CreateObjectContext[TContext](DbConnection
existingConnection)
System.Data.Entity.Internal.LazyInternalContext.InitializeFromModel(DbModel
model)
System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
System.Data.Entity.Internal.InternalContext.Initialize()
System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type
entityType)
System.Data.Entity.Internal.Linq.EfInternalQuery1.Initialize()
System.Data.Entity.Internal.Linq.EfInternalQuery1.Include(String
path)
System.Data.Entity.Infrastructure.DbQuery`1.Include(String
path)
MyProjet.Areas.Administration.Models.BusinessModel.GetBusinesses()
in
D:\projects2010\MyProjet\MyProjet\Areas\Administration\Models\BusinessModel.cs:
line 47
MyProjet.Tests.Administration.ModlelTests.Business.TestGetBusinessesList()
in
D:\projects2010\MyProjet\MyProjet.Tests\Administration\ModlelTests\Business.cs:
line 45
I have tried replacing the existing MyData connection string in the MVC application, and it works fine. It only causes this problem when this is added to the Testing project. Additionally the testing project works without problem when pointed at an SQL or SQL Express Database.
Have been struggling with this for a while now, and just can't figure it out. I am sure I have overlooked something simple.
Try using
Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
See my blog post for an example http://www.arrangeactassert.com/code-first-entity-framework-unit-test-examples/
I have been running the tests under the Built in Microsoft testing framework. Changing the test framework to NUnit (as in Jag's tutorial) has fixed the problem.
So looks like there is a conflict between SqlServerCe and the Visual Studio Unit Testing Framework.