Entity Framework code first causes exception on database access - database

Recently started trying to dig into code first approach for Entity Framework. I have crated some database tables following various tutorials but none of them did the trick.
Starting from scratch about 3 to 4 times now because the exceptions get more and more absurd. Last time created the database on first access but wasn't able to connect to the database in a second debug session because of missing permissions (using integrated security - wat?). Apparently the .mdf was blocked by System process and only a restart in safe mode allowed me to get rid of it.
Anyway, anew. I have a class library, which contains the database models and a gateway class for external access. I have a Console project to test the database creation and access. EF is installed in the class library via NuGet, reference to EntityFramework.SqlServer.dll is added to the Console project.
The connection string looks like this in both projects:
<connectionStrings>
<add name="DbConnection"
connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\LanguageCreator.mdf;Initial Catalog=LanguageCreator;Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
</connectionStrings>
My context class looks like this:
public class LanguageContext : DbContext {
public LanguageContext() : base("DbConnection") {
// Have to set the DataDirectory in code because the wrong one gets set from the config.
AppDomain.CurrentDomain.SetData("DataDirectory", Directory.GetCurrentDirectory());
Database.SetInitializer(new CreateDatabaseIfNotExists<LanguageContext>());
public DbSet<Language> Languages { get; set; }
public DbSet< ... blablabla various other DbSets following, nothing of interest here.
}
This is what my gateway looks like:
public class Gateway {
public void InitializeDatabase() {
using (LanguageContext context = new LanguageContext()) {
context.Database.Initialize(true);
// I did have a configuration class for migration, which seeds some initial data, which is why I'm trying to read the WordTypes here but I left that thing out this time ... will try to add it later on.
IEnumerable<WordType> wordTypes = context.WordTypes.AsEnumerable();
List<Language> languages = context.Languages.ToList();
}
}
}
The call simply looks like this:
class Program {
static void Main(string[] args) {
Gateway databaseGateway = new Gateway();
databaseGateway.InitializeDatabase();
}
}
Now, without absolutely anything special, I recieve the following error on starting a debug session:
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 50 - Local Database Runtime error occurred. Cannot create an automatic instance. See the Windows Application event log for error details.
Unfortunately, the Windows Application event log doesn't show any details to that error. Or maybe I'm too stupid to find it ...
What is actually causing this issue and how can I fix this? Everything I found was about access to external SQL Servers but I simply want EF to create an .mdf locally and connect to that.

I'm very new to Entity Framework and databases in general, but I have a couple suggestions that may help narrow down the issue.
"Verify that the instance name is correct and that SQL Server is configured to allow remote connections." See if the problem is with the server by connecting to it with a different program. If you have trouble connecting to it outside of EF, you can eliminate EF as the problem.
If you can, leave out the connection-string or any mention of your SQL database and see if EF will generate a LocalDB for you. I believe this is the default behaviour of EF. If this works, I think this would also suggest that there's something about your SQL server that's giving you trouble.
Again, I'm very new to this, so just thoughts I'd suggest the way I would try to problem-solve this with my limited knowledge. Hope it's helpful!

Okay, I figured it out on accident. I installed EntityFramework via NuGet in the Console project and voilá, Visual Studio created the .mdf on starting a debug session.
As it still worked after uninstallation of EntityFramework I created the project anew and checked for differences. I found out that the EntityFramework entries in the app.config were still present, so I copied them over to the new project and now that worked as well.
So if you're stuck with the same problem try adding these parts in the app.config of your console project (or whatever project type you use to access your database class library):
<configSections>
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</configSections>
<connectionStrings>
<add name="LanguageCreator.data.LanguageCreatorContext"
connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\MyContext.mdf;Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient"
type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>

Related

Cannot attach the file ".mdf" as database "aspnet-"

I'm using web sockets and SqlDependency to build a game server. An error with the SqlDataReader indicated that I should call SqlDependency.Start. I included the following in my Global.Asax:
SqlDependency.Start(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
This line always ends with the SqlException, with message:
Cannot attach the file 'C:...aspnet-ProjectName-11111111111.mdf' as database 'aspen-ProjectName-11111111111'.
I've been trying to fix this for two days. I've started a fresh MVC 4 WebAPI app, with a basic model, context, and seed, and can't get around this error. I've tried the various solutions in the following:
https://social.msdn.microsoft.com/Forums/en-US/ae041d05-71ef-4ffb-9420-45cbe5c07fc5/ef5-cannot-attach-the-file-0-as-database-1?forum=adodotnetentityframework
ASP.NET MVC4 Code First - 'Cannot attach the file as database' exception
EF5: Cannot attach the file ‘{0}' as database '{1}'
No change. I'm running MVC4 API in Visual Studio 2012, SQL Server is 2014.
This is a DB connection problem, right? The .mdf file in my AppData folder (both it and the log file are there in both projects) can't be connected to SQL Server? Also, help?
I encountered the same problem as you.
In your Web.config file, find you connection string, copy and paste it and then remove everything after the 'MultipleActiveResultSets' - apart from the providerName.
So in mine, it changed from this:
<add name="ApplicationName" connectionString="Data Source=(localdb)\MSSQLLocalDB; Initial Catalog=ApplicationNameContext-20151023111236; Integrated Security=True; MultipleActiveResultSets=True; AttachDbFilename=|DataDirectory|ApplicationNameContext-20151023111236.mdf" providerName="System.Data.SqlClient" />
Became this:
<add name="NotificationConnection" connectionString="Data Source=(localdb)\MSSQLLocalDB; Initial Catalog=ApplicationNameContext-20151023111236; Integrated Security=True;" providerName="System.Data.SqlClient" />
And as you will notice the connection has a different name.
The connections will still query the same database.
Now modify your connection string name in the Dependency.Start parameter to be your the name of the connection string you just created:
SqlDependency.Start(ConfigurationManager.ConnectionStrings["NEW_CONNECTION_NAME"].ConnectionString);
Remove the Initial Catalog property in your connection string.
You should see this answer: https://stackoverflow.com/a/20176660/161471

"Unable to find the requested .Net Framework Data Provider. It may not be installed."

I know that there have been a lot of other postings on this error but none have been able to shed any light or help on my issue. I am using a straight up connection to SqlExpress, so no special Oracle or MySQL databases or anything. It seems like this should just fit like a glove.
So the scenario is this, I have created a solution, comprised of a handful of projects; Repositories, Data (EF5.0), Utilities, a Test project and an MVC Web Application. The goal is to simply access an underlying SQL Express database via the Data classes via repositories in the Repositories project using EF5 and some repositories from the test project and the MVC Application.
The test project works and is able to access and update the database with no issue.
The MVC Web Project, however, is throwing the "Unable to find the requested .Net Framework Data Provider. It may not be installed." error, which I do not understand as it uses the same connection string as the Test Project.
[ArgumentException: Unable to find the requested .Net Framework Data Provider. It may not be installed.]
System.Data.Common.DbProviderFactories.GetFactory(String providerInvariantName) +1426271
WebMatrix.Data.DbProviderFactoryWrapper.CreateConnection(String connectionString) +64
WebMatrix.Data.<>c__DisplayClass15.<OpenConnectionStringInternal>b__14() +16
WebMatrix.Data.Database.get_Connection() +19
WebMatrix.Data.Database.EnsureConnectionOpen() +12
WebMatrix.Data.Database.QueryValue(String commandText, Object[] args) +63
WebMatrix.WebData.DatabaseWrapper.QueryValue(String commandText, Object[] parameters) +14
WebMatrix.WebData.SimpleMembershipProvider.GetUserId(IDatabase db, String userTableName, String userNameColumn, String userIdColumn, String userName) +232
WebMatrix.WebData.SimpleMembershipProvider.ValidateUserTable() +85
I have ...
Registered the System.Data.SqlClient in the web.config.
Verified that the registered version (2.0.0.0) of System.Data exists in the GAC per this article
Made sure that there were no typos in the Connection String.
Here's what I have in the web.config ...
<connectionStrings>
<add name="DBCatalogContext"
connectionString="metadata=res://*/DBCatalog.csdl|
res://*/DBCatalog.ssdl|
res://*/DBCatalog.msl;
provider=System.Data.SqlClient;
provider connection string="data source=.\SQLEXPRESS;
initial catalog=DBCatalog;
integrated security=True;
multipleactiveresultsets=True;
App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
<system.data>
<DbProviderFactories>
<add name="SqlClient Data Provider"
invariant="System.Data.SqlClient"
description=".Net Framework Data Provider for SqlServer"
type="System.Data.SqlClient.SqlClientFactory,
System.Data,
Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</DbProviderFactories>
</system.data>
The only thing I see that doesn't make sense to me is, when I select the "System.Data" reference under the "References" folder and look at the properties it says that it's version 4.0.0.0, but when I change the version in the "DbProviderFactories" section of the config site I still get the error. Also I don't even see the reference to this library in the Test project which works.
I am confident that this is an oversight or that I am missing some config setting, but I do not know where else to look at this point, so any help would be appreciated.
Thanks,
G
I had apparently left out some ultimately pertinent information when I originally posted. This included the fact that the error was being thrown by the membership services; specifically the ... SimpleMembershipInitializer ... originally this class specified the connection string ... "DefaultConnection" defined in the web.config, to be used when initializing the database connection.
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "Users", "UserId", "UserName", autoCreateTables: false);
I had changed it to use the "DBCatalogContext" connection string I had added to the web.config, thinking that I would use this single connection string instead. The problem, of course, is that the new connection string that I added was an Entity Framework connection string which the membership services did not recognize resulting in the data provider error.
I simply added back the original, regular connection string, in addition to the Entity Framework connection string and now everything works. Well everything relating to this issue ...
<connectionStrings>
<add name="DBCatalogContext"
connectionString="metadata=res://*/DBCatalog.csdl|
res://*/DBCatalog.ssdl|
res://*/DBCatalog.msl;
provider=System.Data.SqlClient;
provider connection string="data source=.\SQLEXPRESS;
initial catalog=DBCatalog;
integrated security=True;
multipleactiveresultsets=True;
App=EntityFramework""
providerName="System.Data.EntityClient" />
<add name="DefaultConnection"
providerName="System.Data.SqlClient"
connectionString="data source=.\SQLEXPRESS;initial catalog=DBCatalog;integrated security=True;multipleactiveresultsets=True;App=EntityFramework" />
</connectionStrings>
I hope that someone else can find this helpful.
I had the exact same issues.
I am doing the following:
I extended the UserProfile model to have a new property, Email.
I though I must also add the Email column to this call:
WebSecurity.InitializeDatabaseConnection("AgileBoardDB", "UserProfile", "UserId", "UserName", "Email", autoCreateTables: true);
This never worked, I always get "... Provider not found." I tried everything with no luck.
I turns out that EF is smart enough and automatically creates the Email column so I removed the extra Email parameter from WebSecurity.InitializeDatabaseConnection and all is working fine now.
PS: I am using the same EF connection string to connect to my DB.

0 results on query even though rows exist in Database = 2 databases, but why 2?

I'm using Entity Framework (4.3) and code first (along with SQL server 2012 localdb).
I'm having an interesting situation where in one application a call returns a result ('card') and another using the same query on the same db (with thousands of rows available) returns nothing (null in this case since I'm using FirstOrDefault).
using (var context = new MyEntities())
{
//verify account exists
var account = context.Account.SingleOrDefault(a => a.AccountNum == accountNum);
if (account == null)
{
//handle no account
return false;
}
var card = context.cards.FirstOrDefault(c => c.Used == false);
//check that we actually got a card
if (card == null)
{
//handle no cards available
return false;
}
card.Used = true;
//snip...
context.SaveChanges();
}
In my test console app 'card' will have a value, while in my "service" it does not. Same code (same assembly even), same db, same rows available. The account retrieval works in both cases.
I am going to try this:
How to force EF Code First to query the database?
But even if that works the inconsistent behaviour doesn't make sense to me.
EDIT:
Ends up I have two database instance as pointed out. The interesting part is the datasource changes depending on where the library is run from (as debug under VS11 or from a service running as the admin user). Here's my app.config:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<parameter value="Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True" />
</parameters>
</defaultConnectionFactory>
When I attached to the service process running the same library (DLL) as the console application the datasource has changed from:
(localdb)\v11.0
To:
.\SQLEXPRESS
Same DLL, same app.config. I vaguely remember reading something about named vs unamed local db instances and what user they are run under, however my google skills are failing me currently.
So when I open a connection in SSMS I need to use the appropriate server name depending on which db I'm working with. Not a big deal as this is just the setup for development.
My question:
Does anyone know where this is documented?
The issue was using two databases. Two were being used as I didn't have a .config in the actual running folder with the connection string for my service. The test application had a .config with
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<parameter value="Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
The service did not and therefore fell on the default behaviour (which appears is connecting to the default instance of SQL Server).
I would have rather had the application fail to create the DB (throwing an exception) without a connection explicitly stated, however it is documented by Microsoft in the 'remarks' section of DbContext:
If no connection string is found, then the name is passed to the DefaultConnectionFactory registered on the Database class. The connection factory then uses the context name as the database name in a default connection string. (This default connection string points to .\SQLEXPRESS on the local machine unless a different DefaultConnectionFactory is registered.)

error: 26 - Error Locating Server/Instance Specified

I was doing unit test in the Visual Stdio 2010. However, it kept throw to exception error:
{"A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)"}**
I was searching to solve this problem, and I knew that it was problems of connection between visual studio and sql server. (Maybe, maybe not.)
I was trying to change "App.config" and "Web.config".
Is it right way to fix this problem? If it is yes, can you give example of xml to fix this problem? If it is no, what should i do for fixing this problem?
It's impossible to tell exactly what's going on without code (please post some), but from your comments, I am guessing it's because you haven't correctly set up the SQL connection string.
Most of the time, you would have a connection string specified in the .config file (although you might have it hard-coded in your code?). If you're using something like Entity Framework, app.config might look like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="MyEntities" connectionString="metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
Depending on what your code is doing, it might look different (again, post some code). If you have the code working in an application, but it's failing in the unit tests, you can probably just copy the connection string from the application's app.config file into the unit test's app.config file. If your unit tests don't have an app.config file, just create one.
By the way, the config above is just one example of how you might specify a connection string... your code might require something different.
Hope that helps point you in the right direction...
Update: still would like to see some code, but if it is looking for connection strings out of your database, they typically look something like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="MyConnectionString"
connectionString="Data Source=myserver;Initial Catalog=MyDatabase;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
Hi Every One this is a solution for those who want connect a database with WampServer or Sql Server Management Studio , i try it both and it works both , read carefully , and sorry for my bad english (Tunisian Dev) :
To create a db from classes, using the EF (Entity Framework) Code First method:
  **1. First create the Context Common class exmple:
 Public class MyClassContext: DbContext
 {
       
Public MyClassContext (): base ("name = ConnStringLinkedForDb") {
           
  Database.SetInitializer (new DropCreateDatabaseAlways <MyClassContext>());
}    
 Public DbSet <ClassX> ClassXs {get;set;}
}
      
    
      
  2. In This second point the tag: ,
Would be in the 2 files "app.config" to the data layer and "web.config" in the web layer,In the following two cases:
     2.1. If you want to make a connection with Wamp Server (idUserName = root, pwd = 'empty') and our bd would be on its server:
<ConnectionStrings>
    <Add name = "ConnStringLinkedForDb" connectionString = "server = localhost; user id = root; persistsecurityinfo = True; database = db_name_desired; allowuservariables = True" providerName = "MySql.Data.MySqlClient"/> 
 </ ConnectionStrings>
    2.2.with sql Server Management Studio (ServerName (Source) =YourServerNameInSqlServerManegementStudioProprity(onObjectExplorer), pwd = 'empty') and that our bd would be on its server:
<ConnectionStrings>
  <Add name = "ConnStringLinkedForDb" connectionString = "Data Source = YourServerNameInSqlServerManegementStudioProprity(onObjectExplorer); Initial Catalog = db_name_desired ;Integrated Security = true" providerName = "System.Data.SqlClient" /> 
   </ ConnectionStrings>
**
I had a similar issue. If you had:
Already created the database
Changed development machine/reinstalled SQL server
Attached your previous database
go to your root project folder:
bin->Debug or
bin->Release
locate your .config file
Open with notepad and edit your connection string there
Next (if you had not), open your project in visual studio and locate App.config in Solution Explorer, edit the connection string there to match your current connection.

Microsoft Enterprise Library - How to create database based on Type

I'm using Enterprise Library 4.1.
I have a new feature to implement and it requires the use of mysql.
I have found Enterprise Library Contrib, which adds functionalities to use MySQL with Enterprise Lib.
Works great.
To get it to work, you need to call the method 'DatabaseFactory.CreateDatabase(connectionStringName);' like you would normally do. The connection string name is stored in the configuration and linked to the database provider mapping configuration section.
As an exemple:
<dataConfiguration defaultDatabase="MyDefaultDb">
<providerMappings>
<add databaseType="EntLibContrib.Data.MySql.MySqlDatabase, EntLibContrib.Data.MySql, Version=4.1.0.0, Culture=neutral, PublicKeyToken=null"
name="MySql.Data.MySqlClient" />
</providerMappings>
</dataConfiguration>
<connectionStrings>
<add name="MyDefaultDb"
connectionString=""
ProviderName="System.Data.SqlClient" />
<add name="acb_leaderboards"
providerName="MySql.Data.MySqlClient"
connectionString="" />
</connectionStrings>
Unfortunately, my application will connect to multiple MySQL database and the conncetion will vary from time to time. I can't have the mysql connection string be specified in the configuration.
I want to create a MySQL database object based on the providerMapping configuration.
How can I do that?
Thank you.
PS.
English is not my first language, I'm trying my best.
If you know ahead of time that you're using MySql, and assuming that the MySqlDatabase class follows the same patterns as the Database classes in the core Entlib, then you can just new it up directly, you don't have to go through the factory method.
Database mySql = new MySqlDatabase(currentConnectionString);
should just work. You only need to go through the factory if you're pulling named connection strings from config.

Resources