Why does Entity Framework try to build an already existing database? - c#

In both my Services and WebSite Web.config file, I have the following connection string:
<connectionStrings>
<add name="MyDBConnect" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;Initial Catalog=MyDB;User Id=tester;Password=abc123*123;" providerName="System.Data.SqlClient" />
</connectionStrings>
I manually ran my database build script and have confirmed in the SSMS UI: (LocalDB)\MSSQLLocalDB (SQL Server 13.0.40001 - 8Protons) > Databases > MyDB
While running the project and going to the login screen, an exception is thrown at:
var entity = GetAll().Include(p => p.Role).FirstOrDefault(p => p.Email == userName && p.Password == encryptedPassword && p.IsActive);
with the following message
An exception of type 'System.Data.SqlClient.SqlException' occurred in
EntityFramework.dll but was not handled in user code Additional
information: CREATE TABLE permission denied in database 'MyDB'.
Why is the solution trying to CREATE a table when it already exists? So I went to the table is SSMS and elevated this user's permissions to create a table. The error that now gets thrown is:
An exception of type 'System.Data.SqlClient.SqlException' occurred in
EntityFramework.dll but was not handled in user code Additional
information: There is already an object named 'MyTable' in the
database.
For context, this is after I've cloned someone's EF solution, built it, and am attempting to sign in to a log-in page that the solution is running. So this is a fresh solution on my local machine.

Review the constructor for your database context. For example,
public MyDBContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
this.Database.CommandTimeout = 60;
IDatabaseInitializerCreator creator = new DatabaseInitializerCreator();
Database.SetInitializer(creator.Create());
}
The last two lines will make sure the database and its tables are created, if not already existing and matching exactly what exists.

Related

Entity framework code first with MySql server not able to run migration

I have setup two configuration for migration one is for SQL server and another is for MySql. SQL Server migration is now not being used. Now my problem is when I execute Sql Server migration with Update-Database -ConfigurationTypeName InTouchEnterprise.Data.Repository.MySqlMigrations.Configuration -verbose. It gives me following error
Authentication to host 'localhost' for user 'test' using method 'mysql_native_password' failed with message: Access denied for user 'test'#'localhost' (using password: NO)
But If I run the project it gets successfully connected to the database and do all the operation with database correctly. Now I am clue less what could have been wrong.
According to the error message it says that I am not specifying the password but I have specified password in the web.config. below is my connection string.
<add name="IdentityDB" providerName="MySql.Data.MySqlClient"
connectionString="server=localhost;port=3306;database=rtd;uid=test;password=*******" />
Below is code for Configuration class:
internal sealed class Configuration : DbMigrationsConfiguration<InTouchEnterprise.Data.Repository.InTouchEnterpriseDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
MigrationsDirectory = #"MySqlMigrations";
//for mysql
SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());
}
protected override void Seed(InTouchEnterprise.Data.Repository.InTouchEnterpriseDbContext context)
{
}
}
I don't know the exact issue but when I added persist security info in connection string in web.config to true it started working again. Here is my updated connection string.
<add name="IdentityDB" providerName="MySql.Data.MySqlClient"
connectionString="server=localhost;port=3306;database=rtd;uid=root;password=*****;persistsecurityinfo=True" />

Entity Framework Connection String "The Server was not found"

I have set up a Code First using the following DbContext
public class MyDatabaseDbContext : DbContext
{
public MyDatabaseDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
public MyDatabaseDbContext()
: base("MyDatabase")
{
}
public DbSet<MyTable> MyTables { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
I have also set up the connection string to look at the (Local) database
<connectionStrings>
<add name="MyDatabase"
connectionString="Server=(local);Database=MyDatabase;Trusted_Connection=True;MultipleActiveResultSets=true"
providerName="System.Data.SqlClient"
/>
</connectionStrings>
Also set up the initializer in Global.asax
Database.SetInitializer<MyDatabaseDbContext>(new DropCreateDatabaseAlways<MyDatabaseDbContext>());
I then run the application and call the DbContext (in my case from the controller)
var dbContext = new MyDatabaseDbContext();
var myTableResults = dbContext.MyTables.ToList();
I get the follow error message
An exception of type 'System.Data.SqlClient.SqlException' occurred in EntityFramework.dll but was not handled in user code
Additional information: 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 get a local application data path. Most probably a user profile is not loaded. If LocalDB is executed under IIS, make sure that profile loading is enabled for the current user.
On Debugging and looking at the dbContext variable > Database > Connection > ConnectionString Property I see the following:
"Data Source=(localdb)\v12.0;AttachDbFilename=|DataDirectory|MyDatabase.mdf;Initial Catalog=MyDatabase;Integrated Security=True;MultipleActiveResultSets=True"
Questions
Why is it pointing to the (localDb)\v12.0 database and not my connection string?
Even so, Why is it not creating the database there anyway as this is on my dev machine?
Is there some kind of convention which I have forgotten about which I need to set.
Your connection string needs to be named MyDatabaseDb
OR
your context class needs to be named MyDatabaseContext.
Entity Framework's convention is for the context class to look for a connection string with the same name + Context. The Db in your class name is extraneous.

Added property to Identity model and migrate the database

I have an MVC5 project with Individual user account authentication. I have make a test registered myself and everythings works. Then for test sake I've added a property to ApplicationUser class, now ti looks like this:
public class ApplicationUser : IdentityUser
{
public string NewPropery { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
Then I've opened the Package Manager Console in Visual Studio 2013 and run:
PM> Enable-Migrations
PM> Add-Migration "NewProperty"
PM> Update-Database
first two commands goes well but fail on the third command and this is the error:
System.Data.SqlClient.SqlException (0x80131904): 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)
The database is the usual LocalDb created by MVC template, I leave the connection string in the project as it was created:
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-NyProject.Web-20160325120840.mdf;Initial Catalog=aspnet-MyProject.Web-20160325120840;Integrated Security=True"
providerName="System.Data.SqlClient" />
Where is the error?
UPDATE 1 - After Steve comment
I use to select the project in Package Manager Console, making the project a "Startup project" this will produce a different error There is already an object named 'AspNetRoles' in the database..
This is true. Should I remove pre-existent tables, and what about my data?
You are getting that error because you have not established a baseline initial migration so EF thinks all your objects need to be created. This is because it builds models based on the code and compares it to the snapshot stored in the last migration, so try this:
1) Comment out the new field.
2) Delete the existing migration.
3) Add a baseline migration: add-migration Initial -IgnoreChanges
4) update-database (now EF has a snapshot to compare changes to).
5) add-migration NewProperty
6) update-database
EF Under the Hood

Using both Entity Framework and SqlConnection?

Background
I'm working on a project which contains both legacy code and Entity Framework code. I was advised to use a specific dataservice method to operate on a record from the database. The record was retrieved via Entity Framework, and I passed the PK into the dataservice function to perform the operation.
Preconditions for success and failure
If the network was up, both DB calls (entity and SQL) would succeed. If the network went down, then came back up and this code was executed, then it would retrieve the locked records with entity framework but then fail with the SqlException below.
This got me thinking, what is going on here that might cause the SqlConnection to fail despite EF being able to make the connection.
Code Samples
A code sample follows:
public void HandleNetworkBecomesAvailable() {
_entityFrameworkDataService.ReleaseRecords();
}
EntityFrameworkDataService.cs
public void ReleaseRecords()
{
using (var context = new Entities()) // using EntityConnection
{
var records = context.Records.Where(
record => record.IsLocked).ToList();
foreach (var record in records)
{
_sqlConnectionDataService.UnlockRecord(record.ID);
}
}
}
SqlConnectionDataService.cs
public void UnlockRecord(int recordId)
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["Sqlconnection"].ConnectionString))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = #"UPDATE [Records] SET [IsLocked] = 0";
//etc
command.ExecuteNonQuery();
}
}
}
App.config
<add name="EntityConnection" connectionString="metadata=res://*/FooDatabase.csdl|res://*/FooDatabase.ssdl|res://*/FooDatabase.msl;provider=System.Data.SqlClient;provider connection string="data source=RemoteServer;initial catalog=FooDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
<add name="SqlConnection" connectionString="Server=RemoteServer;Database=FooDatabase;Trusted_Connection=True" />
Now, after discussing with my coworkers, I ended up moving the logic into the entity framework dataservice and doing the work there. But I'm still not quite sure why the connection kept failing.
Edit: The actual error is:
An exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll but was not handled in user code
Additional information: 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: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
Inner Exception:
The network path was not found
But Entity Framework is using the same network path, as can be seen in the two connection strings in the App.config.
Could you be benefiting from entity framework's new resiliency, where it retries transparently? If the error is intermittent, you won't even know it retried, whereas ADO.net is letting you know it fails as soon as it fails. Just checking...

Get data from local DB not working

I have create MVC5 application and I have local DB ,currently I have entered data
to the table and I able to see that in the MDF file under server explorer ->data connections ,now I want to read it via API below and its not working i've provided the ID which I have in the table and I get null ,I think maybe that I need to provide the connection string to the API but not sure how ,any idea how to do that?
This is DB context from the model definition
public class PersonModelDbContext : DbContext
{
public PersonModelDbContext()
: base("Connection1")
{
}
This is the read API
private PersonModelDbContext db = new PersonModelDbContext();
public Person GetPrviderData(string id)
{
Person person = db.Person.Find(id);
return person;
}
This is the connection string in the WEB CONFIG FILE
<connectionStrings>
<add name="Connection1" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\Person.mdf;Initial Catalog=Persons;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
Update - in addition I try with the following without success ,I got error:
db.Database.Connection.ConnectionString = #"Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\Person.mdf;Initial Catalog=Persons;Integrated Security=True";
An exception of type 'System.Data.DataException' occurred in
EntityFramework.dll but was not handled in user code
Additional information: An exception occurred while initializing the
database. See the InnerException for details.
You could try setting your connection string to more this format since it is local
<add name="DataBaseConnectionName"
connectionString="Data Source=[ServerNameHere];User ID=[DatabaseLogonID/Probably sa];Password=[DatabasePassword];Initial Catalog=TheNameoftheLocalDB;"
providerName="System.Data.SqlClient" />
You could try that to establish a connection also don't keep the [brackets] in the connection string.

Categories