MVC .Net can't get it to stop trying to recreate tables - asp.net-mvc

I had migrations enabled - however, now I'm moving to the live server, it appears migrations are still trying to update the database, as I get the error:
CREATE TABLE permission denied in database 'secn'.
I have this in a context file in my models folder:
namespace lhts2.Models
{
public class DefaultConnection : DbContext
{
public DefaultConnection() : base("name=DefaultConnection")
{
Database.SetInitializer<DefaultConnection>(null);
}
}
}
...and in my web.config file, my connection string is:
<add name="DefaultConnection" connectionString="Data Source=[servername];
Initial Catalog=secn; Integrated Security=True;" providerName="System.Data.SqlClient" />
I have deleted the Migrations folder too, and republished - but still I get the error above.
I also have this in my web.config file:
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
Do I need to set the SetInitializer in some other place, other than in the context file in my models folder?
Thanks for any advice,
Mark

From here:
...the initializer should have been set in the static constructor of your context. The static constructor is called before any constructors and is executed once. This is what we want. The reason is that in some of your application, you may initialize more than once the context. You do not want to execute all the process to check if the database if ready to be changed or not.
So, you should change your class to have a static constructor that is only called one time.
namespace lhts2.Models
{
public class DefaultConnection : DbContext
{
static DefaultConnection()
{
Database.SetInitializer<DefaultConnection>(null);
}
public DefaultConnection() : base("name=DefaultConnection")
{
}
}
}

I had the same issue. Setting the IIS user to a "sysad" level user allowed the application to work normally. However that is not a secure method of solving the problem.
Further research revealed that the "migrations" table (named dbo.__MigrationHistory) was the culprit. I had given the IIS user access (Select, Update, Delete, Insert, and References) to all the "application" tables, but not the "migrations" table. Consequently when the application runs and attempts to determine if a migration is necessary, the access fails because of the lack of access rights for that user and the application thinks it needs to create the database and tables - which this user clearly should not have rights to do.
By providing normal access rights to the __MigrationHistory table (Select, Update, Delete, Insert, and References) the IIS user was now able to determine that no migration was necessary and therefore did not attempt to conduct a migration.
Example of Permission Settings Here

Related

Using Effort with EF6 in a DB First approach

I'm using the Model First approach with EF6 and I'm trying to use Entity Framework Effort to develop in-memory tests.
Here is what I do in my test:
var inMemoryConnection = Effort.DbConnectionFactory.CreateTransient("name=MyEntities");
var inMemoryContext = new MyEntities(inMemoryConnection);
MyEntities:
public partial class MyEntities: DbContext
{
public MyEntities(DbConnection dbConnection)
: base(dbConnection, contextOwnsConnection: true)
{
}
When I run the tests, I get an error saying I didn't specify any [key] attributes which is normal since I am not using a Code First approach. Therefor, the OnModelCreating method is called and shouldn't have to.
Is there a way to use Effort in a Model First design without having to add these attributes?
Thanks !
I found my mistake.
Turns out Effort.DbConnectionFactory.CreateTransient is used for Code-First.
Instead if you're working with a .edmx, Model-First, it is Effort.EntityConnectionFactory.CreateTransient("name=MyEntities") you have to use.
I too had a bit of a difficult time in trying to get Effort to work with a DB first, or model first as it's also known, approach. This is what I did to make it work:
Download the Effort.EF6 nuget package
Add the effort.provider to the entity-framework config section:
<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" />
<provider invariantName="Effort.Provider" type="Effort.Provider.EffortProviderServices,Effort" />
</providers>
</entityFramework>
Replace the sql-provider with the Effort-provider in the connection-string:
<connectionStrings>
<add name="testDb" providerName="Effort.Provider" connectionString="metadata=res://*/StaginDB.csdl|res://*/StaginDB.ssdl|res://*/StaginDB.msl;provider=System.Data.SqlClient;provider connection string="data source=testDB;initial catalog=foobaroo;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" />
</connectionStrings>
If your model-first context doesn't offer a constructor you can inject a connection into, you can modify your tt-template to do so:
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
{
// I added this constructor so I could inject a db-connection into the context:
public <#=code.Escape(container)#>(System.Data.Common.DbConnection dbConnection, bool contextOwnsConnection)
: base(dbConnection, contextOwnsConnection)
{
}
// Original constructor
public <#=code.Escape(container)#>()
: base("name=<#=container.Name#>")
{
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
this.Configuration.LazyLoa.... etc. etc.
And we can now use that constructor to instantiate a connection, and an Effort-based in-memory db-context based on this connection:
System.Data.Common.DbConnection connection = Effort.EntityConnectionFactory.CreateTransient("name=KPDBSTAGINGEntities");
TestDbContext testDbContext = new testDbContext(connection, false);
TestDbContext.your-entity.add( new your-entity() { etc. tec. });
TestDbContext.SaveChanges();
Hope this helps.
P.S. Others have had to add a db-provider-factory section to their config. This was not required for me, but maybe for you:
<system.data>
<DbProviderFactories>
<add name="Effort.Provider" invariant="Effort.Provider" description="Effort.Provider" type="Effort.Provider.EffortProviderFactory,Effort" />
</DbProviderFactories>
</system.data>

Create user database via code first ASP.NET MVC

I'm trying to use a MySQL database with asp.net MVC via a code first approach and I don't know how to create the tables, I thought it would create by itself.
I get the message : "Table 'XXX.aspnetusers' doesn't exist"
Do I need to run migrations or something like that?
Thanks
I got a little further by using update-database. You must have change your connection string and your provider to correspond to your MySql
Example :
<add name="DefaultConnection" connectionString="server=127.0.0.1;User Id=root;password=;database=myDB" providerName="MySql.Data.MySqlClient" />
Provider :
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"></provider>
</providers>
</entityFramework>
You should also put this on your dbContext :
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
Thanks

Where is my connection string?

I have created a project call Repository.EF to handle Data access in a n-tire solution. I have added EF to the Repository.EF project where I have all my POCO's . Then I created a DbContext class in that project like this.
namespace LearningSpike.Repositories.EF
{
class GlassContractDbContext:DbContext
{
public GlassContractDbContext() : base("GlassContractContext")
{
}
public DbSet<MetalStock> MetalStock { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new MetalStockConfiguration());
}
}
Then went to package manager console and did
Enable-Migrations
Then set the
AutomaticMigrationsEnabled = true;
Then
Update-Database
Everything is working fine. But the problem is, I don't know where the connection string is. It seems like there is no connectionString in that particular project. I know if I had an MVC4/5 template, there will be a connectionString in the web.config. How can I find the connection string?
How do I configure things now? For example I remember doing this with the connectionString in a MVC5 app
MultipleActiveResultSets=true
How do I do it now?
Thanks!
Cheers!
PS
Also I have the following code in my App.config in the Repository.EF Project
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection,
EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit
http://go.microsoft.com/fwlink/?LinkID=237468 --></configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory,
EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient"
type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
When running the package manager console it will default to use the start-up project (unless you specify the -project param in the command or use the drop down in console manager). From there it will look for your connection strings in the config files of that project. If that is a web project this will be in the web.config.
If you have not added your own connection string to that project, EF will be able to use its own one derived from the project name and create an mdf file which it attaches on the fly during runtime.
If you want to add a connection string (you can do this is any of your config files - however by the sounds of it you want to add this to the app.config in your datalayer project) you can add this below your config sections:
<connectionStrings>
<add name="MyDatabase"
providerName="System.Data.SqlClient"
connectionString="Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;"/>
</connectionStrings>

why connection string is not found from my class library to another class library?

I am having the architecture like this :
Where MVC layer is the presentation layer. EF is class library and Repository is another class library.I am trying to insert data to database from repository by creating the EF context object. Added EF reference into Repository class library. EF having the edmx file. its app.config having the connection string generated by EF.
code is :
public bool CreateUser(User _user)
{
context.Users.Add(_user);
context.SaveChanges();
return true;
}
but while executing this I am getting following exception :
No connection string named 'MyEntitiesConnection' could be found in the application config file.
I tried to add same connection string with same name in repository app.config. but not working. anyone have solution ?
Edited:
connection string is :
<add name="MyEntitiesConnection" connectionString="metadata=res://*/EF.Entities.csdl|res://*/EF.Entities.ssdl|res://*/EF.Entities.msl;provider=System.Data.SqlClient;provider connection string="data source=Servername\MSSQL2008R2;initial catalog=MyDBName;persist security info=True;user id=sa;MultipleActiveResultSets=True;App=EntityFramework;" providerName="System.Data.EntityClient" />
app.config:
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="MyEntitiesConnection" connectionString="metadata=res://*/EF.Entities.csdl|res://*/EF.Entities.ssdl|res://*/EF.Entities.msl;provider=System.Data.SqlClient;provider connection string="data source=Servername\MSSQL2008R2;initial catalog=MyDBName;persist security info=True;user id=sa;MultipleActiveResultSets=True;App=EntityFramework;" providerName="System.Data.EntityClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>
</configuration>
In any .NET application, only one config file is the natural starting point for looking for configuration information. For web applications, that's the web.config file at the root of the application1.
Whilst you may have a file called app.config in your repository project (and, indeed, some VS tooling may have added one) or your EF project, it's not used when you try to read configuration information.
The connection string section needs to exist in the web.config of your MVC app.
1For non-web applications, it's the app.config for the project that produces the .exe file and that gets automatically copied as XXX.exe.config during the build.

Deploying MVC 4 CodeFirst to Azure

I'm trying a 90 day free trial of azure. It is super easy to deploy/publish the website and create the database, but for some reason my tables are not being created in the database. I'm using entity framework 4.4(i believe) and code first migrations. I've read that azure uses its own connection string, but I went ahead and changed my connection strings as well. I Spent hours on this and I can't figure out what is wrong and why my tables are not being created. I deploy website, enable-migrations, add-migration, update-database, then publish with checking the checkbox for code-first. Maybe my connection string is wrong? Any help is greatly appreciated.
In 'MyProject.Web' web.config:
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=tcp:n98my***.database.windows.net,1433;Initial Catalog=slutips_db;User Id=****;Password=****;" />
</connectionStrings>
Then in 'MyProject.Data' app.config, where my datacontext.cs is held:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<contexts>
<context type="SeluCmpsTutorials.Data.DataContext">
<databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion">
<parameters>
<parameter value="slutips_db"/>
</parameters>
</databaseInitializer>
</context>
</contexts>
</entityFramework>
Also I noticed even though all my connection strings are changed, when I add-migration and update-database, it still using the ./sqlexpress local database, how is that possible?
key gotcha to be aware of regarding sql azure connections: for userid it actually usually needs to be user id # server name - do would read youruserid#n98my*** in the connectionstring.
Also, not sure if you need the "tcp:" (not using it) and you may also want to add providerName="System.Data.SqlClient"
Does your db user have necessary permissions for database modification ?
How did you set up your user ?
Initially you should create login for Azure sql server, sometihing like this:
(execute following sql on your server master database, replace angle-brackets values with actual values)
CREATE LOGIN [<SomeServerLogin>] WITH PASSWORD=N'<somepassword>'
Then connect to your slutips_db database as admin and execute following sql
CREATE USER [<slutips_db_user>] FROM LOGIN [<SomeServerLogin>];
GO;
EXEC sp_addrolemember 'dbmanager', '<slutips_db_user>';
GO;
EXEC sp_addrolemember 'loginmanager', '<slutips_db_user>';
GO;
'dbmanager' role allows table creation\management.
'loginmanager' role enables creation of another users in current database (your slutips_db_user will be allowed to execute CREATE USER <slutips_db_user1> FROM LOGIN <SomeServerLogin1> clause
Edit1: Also - ensure that your connection string user have user#n98my*** (user#server) format.
If you follow this tutorial: https://www.windowsazure.com/en-us/develop/net/tutorials/web-site-with-sql-database/ It'll show you how to connect Visual Studio (2012 in the example, not sure if works for any others) with Azure - basically you want to log into the portal, and download the publishing credentials. This will contain your database connection string, which you can then use to push code first migrations up to Azure.
What it looks like you've done is manually added in properties to the app.config yourself. The way the publish works, it defines a local version in your .config file like thus:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
Then, when you publish, VS will auto-magically insert the required stuff into your .config - if I go and FTP to my web site and look at the generated .config file, you see this:
<contexts>
<context type="Web_App.Models.TrackSafeDb, Web App">
<databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[Web_App.Models.TrackSafeDb, Web App], [Web_App.Migrations.Configuration, Web App]], EntityFramework, PublicKeyToken=*******************">
<parameters>
<parameter value="Web_App.Models.TrackSafeDb_DatabasePublish" />
</parameters>
</databaseInitializer>
</context>
</contexts>
So I'd try removing the extraneous stuff from your local app.config and re-publishing
Try adding encryption to your connection string...
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=tcp:n98my***.database.windows.net,1433;Initial Catalog=slutips_db;User Id=****;Password=****;Integrated Security=False;Persist Security Info=True;Encrypt=True" />
</connectionStrings>
what i did was go to my azure management portal.
clicked on databases.
went view connection strings and then copied those directly into my relevant config.
in my case its "release" config.
make sure that the web config transformations are enabled and working correctly.
also make sure you've enabled firewall access to each of the db's...
you have to click "enable connection through firewall" or something similar.
its in the db options on the portal.
After seeing this question for a few days, a couple of thoughts. First, is the name of your context is infact DefaultConnection. Entity Framework (in order to be used with the parameterless constructor) likes the connection string name to match the name of the context.
For instance, if your declare a new context variable as such:
var context = new MyEntities();
Then your connection string should be called MyEntities
<connectionStrings>
<add name="MyEntities" connectionString="Data Source=tcp:n98my***.database.windows.net,1433;Initial Catalog=slutips_db;User Id=****;Password=****;" />
</connectionStrings>
Second, are you 100% sure that there are no web.config transformation files and/or that you also properly updated the connection strings in those files?
Third, remember that upon deployment, any configuration file other than the web.config is essentially ignored. The executing assembly is the web application, not the data project or any others. Any configurations relating to EF setup and deployment should be located in the web.config file (like the snippet that you have in your data app.config)
I had the exact same problem and it was linked to my password containing '%' character.
I checked the resulting web.config on Azure connecting with ftp and the part of my password containing '95%a' turned to '95ยช' ... automagically. That might be a bug in the web deployment feature of azure, because the password was correct in my publish profile locally.
If indeed the resulting password to the DB is corrupted in the resulting connection string, you have to reset it :
From Windows Azure Management, in the SQL DATABASES tab, select the SERVERS list (not the DATABASE list) and click on your server
In the Dashboard, there is a link to reset the admin password
In visual studio, update the password in your publish profile's connectionString (Settings, Databases)
Make a change to the web.config (a real one, not a comment), or it won't be re-published
Publish, and on first use of the database, the migrations will be applied

Resources