I have a codefirst project using EF6 that I would like to reset the database each time the application starts (only in dev)
Is there a way to apply the initial migration followed by the update-database command without needing to do it from the PM window in VS?
I want to remove all data I generate while playing with the application
You could put the following in your Global.asax:
Database.Delete();
Database.SetInitializer(new MigrateDatabaseToLatestVersion<ApplicationDbContext, Configuration>());
ApplicationDbContext would refer to the context you are trying to delete/migrate.
You might want to put a #if DEBUG or some other conditional so it doesn't make it to prod, though.
Related
In my Entity Framework Code First project, if I run the
update-database
command through the Package Manage Console, my Seed() method runs successfully. If, however, I run the command with the -script parameter:
update-database -script
...the Seed() method is not called and the resulting SQL does not contain the SQL commands for seeding the database. This behaviour is repeatable. I'm attempting to create a full DB Script for deployment.
Why is there a discrepancy between the SQL Commands run with -script and without it, and how can I get update-database to run the Seed() method when using the -script switch?
I would argue that this is not a discrepancy, but a by design feature.
For one, when you use -script, the database update is not performed, so the Seed() method should not be called either. And also there is the fact the migrations is a design time tool, and Seed() is a method that has be compiled and called at runtime.
And as for why isn't the contents of the Seed() method included in the generated script, my answer is also the different notions of runtime and design time. Imagine that you have a Seed() method like this:
protected override void Seed(PersonContext context)
{
Random r = new Random();
context.People.Add(new Person("PersonA", r.Next(90));
context.SaveChanges();
}
Now the Random instance is created at runtime, and the Next() is called at runtime. How would you try to compile that to SQL? What if you have a file and you read data from it and put that into the database? These are all things that cannot be evaluated at design time, only at runtime (i.e. if the file is not at the right place at design time, it's not a problem, only at runtime). And that's why a design time tool like the migration scaffolder cannot evaluate it.
I am trying to set up an initializer used in a test environment. From everything I read, DropCreateDatabaseIfModelChanges is exactly what I need. Often times the database gets slightly out of sync with the model, and I need to simply start over fresh.
So here is how I went about setting up my context constructor
public ApplicationContext(int dbID, string username) : base(dbID, username)
{
Database.SetInitializer<ApplicationContext>(new DropCreateDatabaseIfModelChanges<ApplicationContext>());
Database.Initialize(true);
}
However, even when I have this initializer set up, I still get the error:
"The model backing the "ApplicationContext" has changed since the database was created. Consider using code first migrations to update
the database"
some other things to note:
I have tried setting AutomicMigrationsEnabled = false as well as true in my Migrations config file.
I have tried with and without forcing initialization
Anybody run into the same issue or have any ideas?
UPDATE
I was able to look through the source code for System.Data.entity here:
https://github.com/hallco978/entityframework/tree/master/src/EntityFramework
It turns out I needed to outright delete my Migrations/Configuration.cs file to prevent the error. It doesn't matter what the settings are within that configuration file.
I know get a problem because I can't drop the database if I'm using it. Does anyone know if the DeleteDatabase actually means drop the entire database or just the tables the model created?
Just started using VS 2012 and I generated an EF Model from the database. All worked fine, although in my previous experience I had to put a using in my code.
I tried to set up a .cs file with partial classes to provide custom business logic behaviors to the generated classes and Intellisense does not recognize ar prompt with the generated classes.
I did as others have stated and brought up the properties panel of the Edmx model and fount the namespace. However, when I try to put it in a using statement, Intellisense does not recognize it.
Am I missing something here? EF can get very confusing and frustrating if one goes more than an inch or so below its generated surface.
Turns out that EF5 generates a model such that you do not need to have a "using namespace;" or a "namespace xxx"{} in the code file.
Just a simple xxx.cs file and each partial class definition you want to make:
public partial class MyClass
{
}
Background
Visual Studio 2012
NEW Model.EDMX file created in VS2012
Copied some of the EDMX xml from a previously created EDMX into the new one
Problem / Question
Now. The EDMX (TT transform, custom tool, whatever, etc.) is generating BOTH DbContext classes (under the Model.tt/Model.Context.tt files) and ObjectContext classes (via the Model.designer.cs file). See image below:
Everything builds fine and works with the DbContext (but obviously only if I delete the Designer.cs file just before building) but the Designer.cs - and its ObjectContext-based code - keeps reappearing. How do I stop this behavior?!
I didn't find out how to stop the Designer.cs file from generating the ObjectContext, but I did figure out how to make it so that it doesn't matter. Just set the Build Action to "None" instead of "Compile".
The .tt files will generate the code regardless of the code generation strategy in the .edmx. They listen to the .edmx file changes. At least this is how they are working for me.
So by turning the code generation strategy to None in the .edmx you make the .designer.cs file empty of any useful content.
Then open up the project file, find the nodes representing the .edmx, by default it is contained in EntityDeploy node ie the Build Action value, and remove its Generator subkey.
On normal EF Code First projects, Code Generation Strategy is "None" and ObjectContext is not generated.
It appears in your case that you Code Generation Strategy set to "Default".
To stop generating ObjectContext in xxxx.Designer.cs, go to your edmx file, and change your Code Generation Strategy from "Default" to "None".
If you inspect xxxx.Designer.cs
// Default code generation is disabled for model 'C:\Users\xyxy\xyxyxy.Web\Models\xyxy.edmx'.
// To enable default code generation, change the value of the 'Code Generation Strategy' designer
// property to an alternate value. This property is available in the Properties Window when the model is
// open in the designer.
I think the issue is having an EntityModelCodeGenerator value in the Custom Tool field of the .edmx file properties. Just delete that value.
I think this is it, because I notice that in the project that I started off as an EF6 project, there is no value and it has no .designer.cs file, but in the two that I upgraded from EF4, they both have the value and the designer file.
(This equates to a <Generator> tag in the underlying .csproj file.)
I have two projects:
ASP.Net 3.5 website (frontend, UI)
VB Class Library (dataaccess logic)
Where should I save my connectionString, so that I can use if from the class library? And how does this affect where it is placed when I deploy/publish?
Note:
I don't want to pass it to every function in my VB Class
Depending on how you constructed your DAL -- LINQ, TableAdapters, etc. -- it may automatically look for it in the web.config file. If you created the DAL via a designer, likely it stores the default connection string in the app.config file for you class library. I copy the connection strings section from the app.config file to my web.config and change the connection string to the correct database (I have separate web.config's for DEV/QA/PROD). This makes it trivial since the designer generated code already has the code implemented to retrieve it from the configuration file.
If you are hand-coding your DAL and need to pass in the connection string, I suggest setting up a strongly-typed configuration class that interfaces to the web.config and does lazy loading of your configuration values. Use a factory to create your DAL and inject the configuration class into your factory via constructor so that it knows how to create your DAL with the connectionsString retrieved from the configuration file.
My question came from having spent half a day of trying to make this work, but I kept getting the wrong connection when deploying (where I use another database).
My problem was, that I was using
My.Settings.DefaultConnectionString
...To retrieve the connectionString in my VB Class Library.
After following tvanfossons anwer, I dug around some more and found out, that I can simply use (after referencing system.configuration) :
System.Configuration.ConfigurationManager.ConnectionStrings.Item("DefaultConnectionString").ConnectionString
It looks in the web-config for webapplications and app.config for windows/class library apps.
I am glad it now works, but even more glad I know why. ;)
I had the same issue you were having and I ended up using the System.Configuration.ConfigurationManager class to obtain the connection string stored in my web.config file from my class library like Kjensen's answer suggested. This worked wonders, if I had more experience I would vote that answer up.
I needed the connection string to build my Linq2Sql data context, which this method provided me with.
I now build my data context like below (remembering to add a reference to System.Configuration) -
public MyDataContext() : base(System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"]
.ConnectionString, mappingSource)
And as long as the web.config file contains "MyConnectionString" the configuration manager takes care of the rest.
We keep ours in the machine.config of each server and have a custom DAL to handle all DB interaction for our web apps.
Put it in the web.config in the connection strings section.
In the VB project use HttpContext.Current.GetSection to retrieve the section.
A fellow developers idea once was that we should store all the connection strings in a database table.
Don't try doing that. You won't get very far. :)