I am trying to do this tutorial http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/getting-started-with-mvc3-part4-cs but instead of using the compact edition of SQL Server I am using a full install on my local machine. The way I read this tutorial is that the Entity Framework is suppose to create the tables from the objects I have defined. My problem is that I keep getting invalid object name dbo.movies, when I run the project. I finally got it to run by creating the table myself so I know the connection string and everything was correct.
My question is, is it possible to generate tables from objects created in C# and if so how?
is it possible to generate tables from objects created in C#?
Yes it is possible. Did you happen to create the Database manually in Management Studio before running the Code? That could be your problem. With Code First, the default convention is to create the database if it does not exist already. If the database already exists (even without the tables) then it is going to just use the existing database (but it won't try and create the tables).
You can either delete the database and try and run the code again to see if it will create it for you or put the following line in Global.asax:
Database.SetInitializer(new DropCreateDatabaseAlways<YourDbContextHere>());
Once it has run then I would suggest changing that line to:
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<YourDbContextHere>());
These namespaces are defined in System.Data.Entity
The DbContext class also exposes a Database property which defines the following useful methods:
Delete()
Create()
CreateIfNotExists()
So if you defined your class like so:
public class MyContext : DbContext {}
You can construct an instance like so:
MyContext db = new MyContext();
db.Database.Delete();
db.Database.Create();
ModelContext.Database.EnsureCreated();
If you create a Linq-to-Sql DataContext you can inject the structure directly into your Database whith:
DbDataContext db = new DbDataContext(connectionString);
db.CreateDatabase();
I don't know if this is kosher, but using code-first EF, when I use AddRange, EF will typically create all the tables I've defined. I wanted to keep the database because there are other tables I wanted to keep between application runs. I discovered that the tables would not be re-created after they were deleted if I did not also delete the table EF created called __MigrationHistory.
Once I deleted this table, then EF would re-create the tables without having to re-create the database.
This may not be an advisable approach in production, but for my development needs this resolved my issue. Maybe it will help someone else.
You can use FenixRepo library(also available as nuget package) to create particular table, that is a part of you Context. First of all, you should call one time, at startup static Initialize method, where first argument is a factory method, which returns instance of your Context and the second one is an instance of Configuration class. It will prepare SQL scripts for all of your tables, registered at your Context. At case of ASP.NET MVC it is a good decision to paste this code into Global.asax:
FenixRepositoryScriptExtractor.Initialize(() => new Context(), new Configuration());
Then you can create table of desired type MyTable this simple way:
var repo = new FenixRepositoryCreateTable<MyTable>();
//or repo = new FenixRepository<MyTable>();
repo.CreateTable();
Also, if your table spread between several migrations and they have nothing stuff corresponded to other tables, you can specify these migrations(i.e. names of classes from Migrations folder) via FenixAttribute, and exactly they will be used as source of SQL scripts, which will be used for table creation:
[Fenix(nameof(Initial), nameof(MyTableFirstMigration), nameof(MyTableSecondMigration))]
public class MyTable
{
//some stuff
}
Without this attribute, library will use default scripts. It is always better to specify migrations, because otherwise it is not guaranteed that all indexes will be created and also into your migrations you can include some custom code, that will not be executed at case of default solution.
Library is compatible and tested with EF 6.1.3 at case of MS SQL.
Related
We are using Entity Framework Core 2.2 with code first. Sometimes I change one of the entities, but forget to create a new migration, or I create a migration but only in one context (we have for different db engines). I want to check it automatically (ideally as NUnit test) so it runs in our CI server for every commit.
Manually I would try to create a new migration and check that created Up() and Down() methods are empty. It there any way to do it as a NUnit test?
Where is difficulty in creating a test that :
Creates a new DB
Applies all current migrations to create a schema
Tries to use all the entities. It can be as simple as adding an entity, querying that entity and deep-comparing they are the same.
Drops the DB
If the schema doesn't have a migration for new entity or change in entity, you are sure to get and SQL error out of this.
Sure, every time you create a new entity, you would need to add a new test. But that should be already happening if you are using TDD.
And speed shouldn't be a problem either, as creating and dropping a DB shouldn't take more than few seconds and there won't be many of these kind of tests. And they can be parallelized.
If you want to get fancy and don't want to write test for each entity, it could be possible to do something like this :
Use reflection to get all entity types supported by a Context.
Use auto data generator like Bogus or AutoFixture to fill the entities with data.
Round-trip the entities through DB.
Compare the original with retrieved using deep-comparer like Compare-Net-Objects.
The usefulness of such automated approach would depend on complexity of your data model. Would just work for simple model. But would require lots of tweaking and overrides if the model is complex.
I'm new to .NET Core, and I am exploring this particular tutorial: https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/adding-model?view=aspnetcore-2.2&tabs=visual-studio
Now it seems the Entity Framework takes a code first approach to generate the database tables from the created model, and the tutorial uses this scaffolding thing to create the views and controller before generating the tables via the package manager console.
My question is: I was wondering how does the solution really know which models are to be pushed to the database on Update-Database? I have added some standalone model DBSets to the DBContext manually (in the tutorial MvcMovieContext), but that didn't seem to work. Is it the Migrations folder? How does it work?
I would think that this scaffolding step isn't necessary (especially if I would like to maintain the tables without any UI interfaces), and that it has some kind of list somewhere that says which model object goes into database or not.
Entity Framework (Core) works the following: By creating a DbContext or any class that derives from it, EF Core checks for DbSets and their related classes in the code. Take for example this DbContext:
public class StackOverflowDbContext : DbContext {
public DbSet<MyClass> Test { get; set; }
}
As soon as you start with your initial migration (can be done for example via dotnet ef migrations add Initial), EF checks for a DbContext class. If there are multiple, you need to specify that, otherwise it takes the first available and analyses it. In this case, the MyClass needs to be added to the database and therefore the class and all it's properties start to appear in the initial migration.
From there, you can update your model whenever you want, but do not forget to create a new migration after that.
I would think that this scaffolding step isn't necessary
And yes, that is true. You don't need to use scaffolding, it's just there for providing a starting point.
You must to create a migrations and update your db. You can find commands here
http://www.entityframeworktutorial.net/efcore/entity-framework-core-migration.aspx
I've an existing database with many (~500) tables and stored procedures. Whenever the database gets updated, I need to re-generate the .edmx file for Entity Framework 6 based on the new schema; the process produces about 500 files, one per each table and at least one per each stored procedure that returns results.
For various reasons, I'd rather have a single file with all classes in it.
I know I can comment out this line <EntityModelName>.tt to consolidate all files:
// fileManager.Process()
However I can do this only after Entity Framework generated 500+ files. Having to do this every few days gets quite annoying.
Updating the .edmx file instead of deleting and re-generating it often results in errors due to DB schema issues that won't be resolved anytime soon.
What would be the best way ensure that only one .cs file generated from the outset? I am willing to go as far as forking EntityFramework, modifying VS templates, or doing other unconventional things as necessary.
You can use this tool which you can configure to generate all your POCOs into a single file (by default) or to separate files, also it has more options can you look at and check through the video exists on the link that I've mentioned.
Remember that you can switch between code-first and database first by just setting the context's initializer to null, so something like :
public class MyDbContext : DbContext
{
static MyDbContext()
{
// I don't want to initialize my database from code, I already have a database.
Database.SetInitializer<MyDbContext>(null);
}
//
//
// you dbsets goes here
}
You can find more details about initialize db contexts here.
So in a few words you can use the tool to generate the POCOs for you and still use your database, which is much cleaner than using EDMX files.
Let me know if you need more details or if you still confused.
I am working on some project at the moment and I have to use local database. So, I created a new service-based database (no tables atm). Then I wanted to add Entity Framework support.
Because I never used Entity Framework before, I was referring to that link: http://msdn.microsoft.com/en-us/data/jj200620.aspx.
Everything is OK, but here it gets complicated. I created my DataContext class with DbSet inside it. But, when I run my unit test, table is created on Localdb (not inside my .mdf file).
What to do?
I am pretty sure, that I did choose which database to use correctly (actually did that 3 times already), but still, data tables are created on LocalDb. What I am doing wrong here?
I am complete beginner with that (been only using doctrine ORM). Otherwise I can insert data and all, it is just on the wrong database.
When your doing code first development in EF, you can force EF to only ever consider one connection string name.
One of the constructors (of which there are quite a few overloads) on the EF Data Context parent classes, takes a simple string.
This string is given to be the name of a connection string in the App or Web config to use.
You make the call something like this:
using System.Data.Entity;
namespace MSSQL_EFCF.Classes
{
public class DataAccess : DbContext
{
public DataAccess() : base("myConnectionString")
{}
public DbSet<MyTableObject> MyObjects { get; set; }
}
}
You can still put any code you need for your own start-up (Such as DB Initializer calls) inside your constructor, and all that will get called once the base call completes.
The advantage of doing things this way forces entity framework to always use the named connection string and never anything else.
The reason this catches many developers out, and why it runs off an uses localdb is deceptively simple.
The Entity Framework DbContext by default will use the name of the data context derived class as a database name, and if it can't find a suitable connection string in any config file by that name, makes the assumption that your working in development mode without a full backing data store.
In my example above, EF would examine App and/or Web.config for a connection string called "myConnectionString"
Once it makes this development decision, it knows that localdb will be present as this gets installed with the latest builds of visual studio, and so it will automatically seek out a connection and populate it with a db that follows the name of the context in which it's used.
I've previously written a blog post on the subject, which you can find here :
http://www.codeguru.com/columns/dotnet/entity-framework-code-first-simplicity.htm
NOTE: The above applies to any database that you connect with using EF, it's the connection string that decides what/where the actual data store is.
We are using the Code-first approach without an Edmx file, its running fine to create database the first time.
But if I am adding new data entities say new class to my database context then it is not able to add that to new table in that database.
Say for example there are two table initially in database.
ex Database : DbTest
Table : Tbl1, Tbl2
Now if I add new table, say class name 'Tbl3', then it should be adding it into the existing database.
Can any one please explain to me with an example how it can be achieved via code first approach?
I have seen mentioned something like Database.SetInitializer(new ........)
What do I need to put in the blank area of the constructor above?
If you look in your database you will see a table called "EdmMetadata" which Entity Framework uses to determine if any changes have been made to your model since the database was created (which it has in your case).
The default behaviour is for an exception to be thrown if the model and database differ. To get different behaviour you will need to use an IDatabaseInitializer<TContext>.
Luckily, Entity Framework ships with some default implementations of this interface:
CreateDatabaseIfNotExists<TContext> - This will create the database if one doesn't already exist.
DropCreateDatabaseAlways<TContext> - This will re-create the database each time your application is run.
DropCreateDatabaseIfModelChanges<TContext> - This will re-create the database if a change is detected in the EdmMetadata table (usually as a result of creating new tables).
You can of course also create your own implementation of this interface by overriding the InitializeDatabase method.
an example of using one of these initialization strategies is shown below:
Database.SetInitializer(
new DropCreateDatabaseIfModelChanges<NameOfYourDbContextClass>())
Think carefully before choosing an initialization strategy as you could end up losing data already entered into the database and this may not be what you want.
The implementations provided by Entity Framework provide a Seed method for loading your database with data so that you can preload your database with default data each time it is created.
This article provides further information.