I'm using EntityFramework 6.1.3. I have generated models from an existing database. Now, when trying to query the database, datacontext returns null. The database appears to be empty.
But the database is not empty as I can connect and query it using LINQPad. When googling the problem I came across a similar situation. In that case the EF generated an empty database on the local server and the solution was to tweak the connection string, although without clear details what exactly should be changed.
However, I'm not sure if that is the case in my situation.
My connection string is pointing to the remote server.
It is not possible that the database was created on the remote server, as we don't have authorisation.
The database was not created on my local machine as I dont even have local sql server installed. And my AppData folder is empty.
Any suggestions?
Generated connection string below
<add name="MAST_DEV" connectionString="metadata=res://*/Models.Mast_DevModel.csdl|res://*/Models.Mast_DevModel.ssdl|res://*/Models.Mast_DevModel.msl;provider=System.Data.SqlClient;provider connection string="data source=xxxxxx;initial catalog=MASTER_DEV;user id=xxxxx;password=xxxxxx;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
I don't really know what I was doing wrong. I have created simple project from scratch , generated models again and it does work fine now. Possibly, previously I selected 'Code first from the database' from Entity Data Model Wizard. Whereas this time 'EF Designer from the database'. Anyway, thanks for trying to help. It was my mistake
This is the exact solution for my problem (the answer is copied from here Entity Framework cant use the DbContext, model being created)
"I see you are using the EDMX with Templates (.tt) for generating the classes. But if you are getting the information from a existing database, the wizard will create a ConnectionString compatible with ObjectContext (metadata informations and provider of entityframework).
The problem is that the connectionstring you are using is for ObjectContext (Database First and Model First). For the DbContext you should use the connectionstring without the metadata informations"
Related
I am developing an application in which the database is selected by the end user at runtime. The database can either be on a MS SQL server or an IBM DB2 server. I am currently using IBM DB2 10 Express-c on a windows server for testing. I am developing using Visual Studio 2013 C# and Entity Framework 6. I have installed the EntityFramework.IBM.DB2 Nuget package for the DB2 support. I am using reverse-engineer code-first against an existing SQL server database to generate my base code. The application works fine against a SQL Server database.
I am using System.Data.Common.DbProviderFactories.GetFactory to generate the provider.
System.Data.EntityClient.EntityConnectionStringBuilder connectString = new System.Data.EntityClient.EntityConnectionStringBuilder(a_Connection);
System.Data.Common.DbConnection conn = System.Data.Common.DbProviderFactories.GetFactory(connectString.Provider).CreateConnection();
conn.ConnectionString = connectString.ProviderConnectionString;
LB500Database = new LB402_TestContext(conn, true);
a_Connection is provider=IBM.Data.DB2;provider connection string="Database=LISTBILL;User ID=xxxx;Password=yyyy;Server=db210:50000"
and is being parsed correctly by the EntityConnectionStringBuilder.
I then try to access a table in the database with
LBData500.LB_System oneSystem;
System.Linq.IQueryable<LB_System> allSystem = LB500Database.LB_System.Where(g => g.DatabaseVersion == databaseVersion && g.CompanyID == companyID);
I get an invalid operation exception "Sequence contains no matching element" which means that no elements are returned. If I remove the Where so that all rows are returned (there is one in the table) and try to enumerate the result set using the VS debugger I see the message:
"The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe."
I am not using multi-threading. I am not inside the OnModelCreating.
Just changing the connect string to point to SQL server works fine, so I think my basic approach is sound. If I were getting some kind of error back from the server I would have something to go on. I can run the query from inside Visual Studio, so I have connectivity.
Any pointers would be appreciated.
UPDATE:
I turns out the EF objects were generated using EF5 and the EF6 runtime was being used. I regenerated the EF objects using EF6 reverse engineer code first. I can now connect to the database and get an error message:
"ERROR [42704] [IBM][DB2/NT64] SQL0204N \"DBO.LB_SYSTEM\" is an undefined name."
The schema in the DB2 database is the same as my userid (in this case, not always). I added the CurrentSchema=xxxx to the provide connection string, but EF is still passing dbo as the schema name.
Now I need a way to change the schema name at run time. I saw a link to codeplex EFModelAdapter (http://efmodeladapter.codeplex.com). So I may give that a try.
Update2 After looking through EFModelAdapter, I decided to take a different route. Since I only need database access and not schema management, I decided to go with Dapper (https://github.com/StackExchange/dapper-dot-net). This works great for what I need and allows me to change the schema name when accessing DB2 databases.
As per my Update 2, Entity Framework was a little overkill for what I needed. I switched to dapper https://github.com/StackExchange/dapper-dot-net and I am working fine against multiple DBMSs.
New to EF.
Am using code first but created from an initial database.
First issue is when I added a foreign key to the model After executing add-migrations from the console it created migrations to create the entire tables rather than just adding the foreign keys to the existing tables using AddForeignKey(....),
And when I try to update-database it tries to create a localdb database under and i get the error
Directory lookup for the file "C:\src\Project\App_Data\TheDatabase.mdf" failed with the operating system error 2(The system cannot find the file specified.).
CREATE DATABASE failed. Some file names listed could not be created. Check related errors.
Which kind of makes sense because i'm not using sqlexpress.
It seems as though I need some configuration to coax it into action.
Any useful advice would be welcome.
I found a solution although maybe this is more of a workaround
I did change the connection factory but it did nothing. Still tries to use App_Data folder and looks for an MDF there.
I found a work around though. The package manager lets you override the connection string so i just did that and it works fine.
As for the other part of my question regarding why it was trying to create the tables. What I needed to do first it use the Add-Migration with -IgnoreChanges and update-database will then store an initial blank migration so from then on, any changes you make will be just those incremental ones I was referring to.
Here was the link for that. https://msdn.microsoft.com/en-us/data/dn579398.aspx?f=255&MSPPError=-2147217396
Thanks to those who offered help.
Hope this helps. Basically, EF needs your first snapshot of your database to create the model classes as the initial state, after that you can add migrations.
If it doesn't help, can you post your connection string and number of migrations your have?
I have a class library with EF Code First. I just upgraded to EF 4.3 and now I want to enable migrations.
I type Enable-Migrations -ProjectName MyProjectName in the PM console but receive the following error
PM> Enable-Migrations -ProjectName MyProjectName
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at System.Data.Entity.Migrations.DbMigrationsConfiguration.GetSqlGenerator(String providerInvariantName)
at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext)
at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration)
at System.Data.Entity.Migrations.Design.MigrationScaffolder..ctor(DbMigrationsConfiguration migrationsConfiguration)
at System.Data.Entity.Migrations.Design.ToolingFacade.ScaffoldRunner.RunCore()
at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()
The given key was not present in the dictionary.
PM>
I cant figure out what dictionary that might be wrong.
My connection string looks like this:
<connectionStrings>
<add name="MySystem" connectionString="Data Source=MyServer\Instance;Initial Catalog=myDbName;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
Any idea about what might be wrong?
Just a note:
I use my class library in a console application with an exact copy of my app.config and there I can access my database perfectly well.
It turned out Anders Abel was right in the cause, but we found a much simpler solution.
According to the mvc-mini-profiler page there is a special package in Nuget called MiniProfiler.EF that does not requires any wrapper around the SqlConnection. We dropped our old mvc-mini-profiler and installed the MiniProfiler.EF. Then Enable-Migrations worked as expected.
EF Code First has an extensible provider model for Sql code generation. The documentation for DbMigrationsConfiguration.GetSqlGenerator says what it does:
Gets the SQL generator that is set to be used with a given database
provider.
The MvcMiniProfiler wraps itself around the DB provider to add profiling support. To EF it will look like you're using a MvcMiniProfiler DB and not a MSSQL DB. Unfortunately EF Code first doesn't know how to handle a MvcMiniProfiler DB.
A possible fix would be to add a SqlGenerator with the MvcMiniProfiler name that wraps the Sql Server generator.
Edit
Looks like it might be possible to just reregister the existing sql server generator for the mvc mini profiler name (if you figure out the name of it).
At http://romiller.com/2012/01/16/customizing-code-first-migrations-provider/ there is code snippet that shows how to register a provider:
public Configuration()
{
AutomaticMigrationsEnabled = false;
SetSqlGenerator("System.Data.SqlClient",
new CustomMigrationsProviders.CustomSqlServerMigrationSqlGenerator());
}
This may be a related, but different problem, but since it was Anders' post here that lead me to the solution, I figured I post this solution here as well.
The Problem:
If MiniProfiler is initialized before our Entity Framework database initialization strategies execute, the initialization fails with an error about a missing migration table.
If the Entity Framework database initialization strategies execute first, access to entities fails with a type casting exception as the MiniProfiler DbConnection is tried to be forced into a SqlConnection variable (in an internal generic).
The Cause:
When MiniProfiler initializes, it uses reflection to retrieve a collection of database providers from a private static field in System.Data.Common.DbProviderFactories. It then rewrites this list with MiniProfiler shim providers to replace the native providers. This allows MiniProfiler to intercept any calls to the database silently.
When Entity Framework initializes, it starts to compile the data models and create cached initialized databases stored in System.Data.Entity.Internal.LazyInternalContext inside some private static fields. Once these are created, queries against the DbContext use the cached models and databases which are internally typed to use the providers that existed at initialization time.
When the Entity Framework database initialization strategy runs, it needs access to the bare, native Sql provider, not the MiniProfiler shim, in order to correctly generate the SQL to create tables. But once these calls to the native provider are made, the native provider is cached into LazyInternalContext and we can no longer inject the MiniProfiler shims without runtime failures.
My Solution:
Access the private collections inside System.Data.Entity.Internal.LazyInternalContext and clear out the cached compiled models and initialized databases.
If I perform this purge between the operation of the EF database initialization strategies and the initialization of MiniProfiler, the MiniProfiler shims can then be inserted without causing later runtime failures.
Code:
This code did the trick for me:
Type type = typeof(DbContext).Assembly.GetType("System.Data.Entity.Internal.LazyInternalContext");
object concurrentDictionary = (type.GetField("InitializedDatabases", BindingFlags.NonPublic | BindingFlags.Static)).GetValue(null);
var initializedDatabaseCache = (IDictionary)concurrentDictionary;
if (initializedDatabaseCache != null) initializedDatabaseCache.Clear();
object concurrentDictionary2 = (type.GetField("CachedModels", BindingFlags.NonPublic | BindingFlags.Static)).GetValue(null);
var modelsCache = (IDictionary)concurrentDictionary2;
if (modelsCache != null) modelsCache.Clear();
Warning:
It appears that the names of the internal fields in LazyInternalContext change between versions of EF, so you may need to modify this code to work with the exact version of EF that you include in your project.
I've got an existing EF4.1 project which is working just fine. I've added a new SP to the DB which returns a new kind of an entity (an existing entity with some additional fields).
The problem is when I try to import the function to the EF - it won't create my complex type. the wizard writes that "no database connection has been configured for this model". Which is strange - because it does see the new SP and everything.
I've tried creating my own, new complex type, but it won't map the fields as needed (some type conversion issues)
Any ideas what could be done?
Thanks!
To build on Malako's answer, I have a simlar situation. My problem was that my connection strings are in an external file
<connectionStrings configSource="some_other_file.config">
The "Update Models" wizard has a bug where it will not look in the external file for connection strings, and I cannot leave a connection string in the connectionStrings tag since it must be empty or it will give an error when building.
The workaround for me is to use the Update Wizard, check the box that says "Save entity connection string in Web.config", and then add all my function imports. When I'm done, I comment out the connectionString so my project will build. Next time, uncomment that entity connection string before updating models.
Annoying, but at least there's a way to get it to work.
For me, how I got it to work in my model project. There was other connection strings I left in there that had "server=" in there (non-EDMX related). I just deleted those other connection strings and the EDMX update wizard works as advertised.
Error message seen: Unable to update the App.Config file because of the following exception: 'The 'server' keyword is not supported.'
I assume the ConnectionString property of the entity model is empty. Check in model browser.
The easiest way to fix this is to remove all the connection strings in the .config files. Do a search for
connectionstring="
Delete the line(s) entirely or comment it/them with
Delete your edmx and recreate it. Make sure 'Save entity connection settings in Web.config as:' is checked.
Now the ConnectionString should be set and you will be able to generate complex models via function import.
if it still not works for you then remove other connection strings. and re add new.
the same problem is solved by this. removing all the connections string and added the Entity framework's connection string first then added the others but changed the name.
My solution to this same problem (VS2013) was this:
Go to Model Browser
Right click YourModel.edmx
Update Model from Database
Then it prompted me to select the connection. I selected the connection I wanted and proceeded to the next screen.
Add/Refresh/Delete what you need.
Select Finish and voila, the connection is here.
You have to add the connection string again every-time you add a stored procedure. Otherwise it will be no map when you try to get the columns you get a message on the "Edit Function import" you will See a message saying "No database connection has been configured for this model".
So my workaround is to re install the stored procedure again but what happens when I have 20 or more then every time I will have to re do all stored procedures. Or create a new model, this is the cons of this.
Here is the link of my solution there is a video and everything but I'm trying to figure How to do it with out deleting the model or adding the connection string VIDEO LINK OR stack overflow solution since there is not way yet to map store procedure I use a class my company has to retrieve has table from the store procedure and then send the data as JSON String if you want that solution let me know and then I will tray to do the code with the explanation (its done with a .dsn conection string and ODBC "Open Database Connectivity").
I did (pretty much) everything correct in a new EF project, but I forgot to use the named connection string in the EF context class, so, it used the default.
It created a new database inside the SQL Express default data directory, and it worked perfectly.
When I realised my mistake (After wondering for ages why no files were showing up in the app_data folder), I renamed the class to use the named connection string and then I kept getting the following error:
Unable to complete operation. The
supplied SqlConnection does not
specify an initial catalog.
I know how to fix this, but, EF is like magic to me! I can't believe it works as well as it does and I am just curious as to what it uses by default / is there a list anywhere of "assumptions" that EF uses on your behalf if you specify nothing?
By default it uses database with the same name as your context but once you specify custom named connection string you must provide the name of used database either by Initial Catalog or Database parameter.
I had the same problem but I figured it out by changing the web.conf. You need to specify an initial catalog and Integrated security and make a user instance.
Here is working web.conf:
add name="MovieDBContext"
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|Movies.mdf;Initial Catalog=Movies;Integrated Security=SSPI;User Instance=true"
providerName="System.Data.SqlClient"