How to create all tables on database when application is loading? - c#

I'm learning about Entity Framework and I want to create a project with it. I've use FluentNhibernate in my project but now I want to try Entity, but I have a doubt about how to create all tables(DBSet) when the application is loading. In my case I have 3 tables: Cliente, Produto, Venda, that I want to create when application is loading but I don't know how to do this.
How could I do this ?
trying
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public class DatabaseContext : DbContext{
public DatabaseContext():base("default"){
Database.SetInitializer<DatabaseContext>(new CreateDatabaseIfNotExists<DatabaseContext>());
//Database.CreateIfNotExists();
}
public DbSet<Cliente> clientes { get; set; }
public DbSet<Produto> produtos { get; set; }
public DbSet<Venda> vendas { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder){
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Produto>()
.Property(p => p.valor)
.HasPrecision(9,2); // or whatever your schema specifies
Database.SetInitializer<DatabaseContext>(null);
base.OnModelCreating(modelBuilder);
}
}

Assuming you already have all your DbContext and Entities setup and you are just asking about generating/updating the database, you are looking for Entity Framework's migration features.
Open Package Manager Console and run the following commands in your project:
// Enable migrations to your project
Enable-Migrations
// Add migrations to your project
Add-Migration
// Update any changes to the generated database
Update-Database
More details here:
https://martinnormark.com/entity-framework-migrations-cheat-sheet/

In the OnModelCreating method remove:
Database.SetInitializer<DatabaseContext>(null);
i suggest you to read:
http://www.entityframeworktutorial.net/code-first/database-initialization-strategy-in-code-first.aspx
and about automatic migration:
http://www.entityframeworktutorial.net/code-first/automated-migration-in-code-first.aspx

Related

How to "re-pluralize" database tables after moving from .NET 4.5 to .NET Core 2.2?

I have a project that I'm moving from .NET 4.5 to .NET Core, for some reason (that I can't remember), I wanted to prevent pluralization of the table names when I ran an update-database like so (.NET 4.5):
public class UncoveredLink : DbContext
{
//removed constructor for brevity
public DbSet<Album> Albums { get; set; }
public DbSet<Artist> Artists { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//the line I'm talking about is here
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
So, when I look at my database in SQL Management Studio I see the following:
//what I see
dbo.Album
dbo.Artist
//what i want
dbo.Albums
dbo.Artists
I believe the lack of pluralization is what is causing this error when I try and load a page:
SqlException: Invalid object name 'Albums'.
//further down the stack trace i see
UnLink.Services.AlbumService.GetAlbumByStringExt(string stringExt) in AlbumService.cs
album = _db.Albums.Where(x => x.StringExt == stringExt).FirstOrDefault();
See? I'm trying to call _db.Albums but I believe I can't do this because the table is not pluralized and my Core Context doesn't have a pluralization OnModelCreating like my .NET 4.5 did (can't seem to add it).
My new DbContext in .NET Core 2.2 looks like this:
public class ApplicationDbContext : IdentityDbContext
{
public DbSet<Album> Albums { get; set; }
public DbSet<Artist> Artists { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
How can I update the table names? The tables in my Core DbContext (as seen above) are already pluralized so I can't make a change to the DbContext that would be tracked for a new add-migration... do I just manually create a migration file and update the table names like:
migrationBuilder.RenameTable(name: "Artist", schema: "dbo", newName: "Artists", newSchema: "dbo");
I thought it wasn't good practice to create a migration for something that wasn't actually changed/tracked in the code?
I think it can be helpful:
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
modelBuilder.Entity<Album>()
.ToTable("Album");
}
another way is:
[Table("Album")]
public class Album
{
public int AlbumId { get; set; }
public string Name { get; set; }
}
Well, you have made a change in the code, because you used to have that line about Remove<Pluralizing>, but now you don't. Unfortunately, Add-Migration might not pick up this change, especially when you're converting to .Net Core at the same time.
Since your model doesn't match your tables, you have the following options:
Manually create a migration that changes the table names:
migrationBuilder.RenameTable("Album", newName: "Albums");
OR
2. Write a query directly to the Db in SQL to change the table names:
EXEC sp_rename 'dbo.Album', 'dbo.Albums';
EF Core 2.0 introduces a new IPluralizer service that is used to singularize entity type names and pluralize DbSet names.
Maybe you could look into that. Plenty of posts about this on here or here's a blog post about that

Entity Framework added extra `s` to table name in runtime query if add `PluralizingTableNameConvention` to avoid extra `s` it throw error

I have simple context with 3 tables.
database tables are already present but using code first approach.
Model Device.cs is -
public class Device
{
public System.Guid Id { get; set; }
public string Name{ get; set; }
}
public class sampledbContext : DbContext
{
public sampledbContext ()
: base("name=sampledbContext ")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
public virtual DbSet<Device> Devices { get; set; }
}
To avoid extra s I have added above line into OnModelCreating but it is giving an error -
System.InvalidOperationException: 'The model backing the 'sampledbContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).'
Database was already created and I try to use code first approach here.
I have not done update-database yet.
I tried doing Enable-Migration and Update-database it creates table with name s like Devices why ? s is added ?
You've turned off auto-migrations in the line:
Database.SetInitializer<IoTSimulatordbContext>(null);
And therefore you will need to run update-database manually to update the model (you can run this via package manager console). If you have any data in your tables it is likely that the migration will fail due to the possibility of losing data, in that case you will need to either delete all data from the tables first or make a custom migration script to handle copying the data first. As this seems like a test it may be better to restart the migration project with the pluralisation off from the beginning.
You can add a DataAnnotation to describe the Schema and Table name to your Table class such as this;
[Table("Device", Schema = "MySchema")]
This will give you more control over the naming.

Can't access database when I change asp.net mvc model properties

I'm developing a project and I made changes to my models, and now whenever I run my project I get these errors for all the model that I made changes to:
for my person model:
Invalid column name 'Location'.
Invalid column name 'EmailAddress'.
Invalid column name 'PlaceOfBirth'.
for my guardian model:
Invalid object name 'Admission.Guardian'.
Here is my DbContext model:
public class SchoolInfoEntities: DbContext
{
public DbSet<Students> Student { get; set; }
public DbSet<Class> Classes { get; set; }
public DbSet<Guardian> Guardians { get; set; }
public DbSet<Staff> Staffs { get; set; }
public DbSet<Subject> Subjects { get; set; }
public DbSet<Department> Departments { get; set; }
public DbSet<SchoolDetails> SchoolDetails { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Students>()
.HasMany(t => t.Guardians)
.WithMany(t => t.Students)
.Map(m =>
{
m.ToTable("Admission.StudentGuardian");
m.MapLeftKey("StudentId");
m.MapRightKey("GuardianId");
});
modelBuilder.Entity<Staff>()
.HasMany(t => t.Subjects)
.WithMany(t => t.Staffs)
.Map(m =>
{
m.ToTable("Admission.SubjectInstructor");
m.MapLeftKey("StaffId");
m.MapRightKey("SubjectName");
});
modelBuilder.Entity<Staff>()
.HasMany(t => t.Departments)
.WithMany(t => t.Staffs)
.Map(m =>
{
m.ToTable("Admission.StaffDepartment");
m.MapLeftKey("StaffId");
m.MapRightKey("DepartmentId");
});
Database.SetInitializer<SchoolInfoEntities>(null);
}
}
Is there anything that I'm not considering? Please help me guys.
You can't change the model fields without updating the related database fields. You need to create a migration and apply it in order to keep your models in sync with the database schema.
https://docs.asp.net/en/latest/data/ef-mvc/migrations.html
If you have a production version of the database you'll need to run the same migrations on it.
You need to run below commands on the Package Manger console before run your app.
Note : you need to set correct connection string where the place (db server) you need to run the scripts.
PM> Add-Migration "Added_New_Properties"
PM> Update-Database
Since you are using Code First, EntityFramework always make sure that the model is synchronized with the database, when the application starts, it compares the classes and its properties with the tables and columns in the database taking into consideration any changes you made using the Fluent API inside your Context.
When you add a new property into any class, you have to either add a corresponding column in the database table that maps to this class, or you can let EntityFramework do it for you by using Migration.
You have to enbale migration first using the Enable-Migrations command
After that, run the command Add-Migration [Migration Name] which will compare the model to the database and generate some code inside the Migrations folder to update the database, it should have an Up and Down methods.
To run the Up method which updates the database to the code, you have to run the Update-Database command.
All of these commands must run inside the Package Manager Console which you can reach from Tools -> NuGet Package Manager -> Package Manager Console.

Custom HistoryContext causes Get-Migrations to fail

I'm using Oracle's Entity Framework 12.1.22 (6.121.2.0) and Entity Framework 6.0.0.
I have a custom HistoryContext that ensures the __MigrationHistory table is in the same schema as the rest of the model, because we have multiple applications using the same database.
When I start from scratch and run Update-Database from the Package Manager Console, everything appears to work fine, and the __MigrationHistory table is exactly where I expect it to be. However, it quickly becomes obvious there's a problem:
PM> Update-Database -TargetMigration:0
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Target database is already at version 0.
PM> Add-Migration 2
Unable to generate an explicit migration because the following explicit migrations are pending: [201601221958588_1]. Apply the pending explicit migrations before attempting to generate a new explicit migration.
PM> Get-Migrations
Retrieving migrations that have been applied to the target database.
No migrations have been applied to the target database.
The problem is that Get-Migrations is not looking in the correct schema for the __MigrationHistory table - it's looking in the user schema for the user named in the connection string. I verified this by creating a copy of the __MigrationHistory table there, at which point all of the above commands began to work as expected.
Can anyone point out what I'm doing wrong?
public class MyContext : DbContext
{
public MyContext()
: base("name=Blue")
{
}
public virtual DbSet<MyEntity> MyEntities { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema("BLUE");
}
}
public class MyEntity
{
[Key, MaxLength(80)]
public string Name { get; set; }
}
public class MyDbConfiguration : DbConfiguration
{
public MyDbConfiguration()
{
this.SetHistoryContext("Oracle.ManagedDataAccess.Client",
(connection, defaultSchema) => new MyHistoryContext(connection, defaultSchema));
}
}
public class MyHistoryContext : HistoryContext
{
public MyHistoryContext(DbConnection dbConnection, string defaultSchema)
: base(dbConnection, defaultSchema)
{
this.defaultSchema = defaultSchema;
}
private string defaultSchema;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.HasDefaultSchema(this.defaultSchema);
}
}
I used the instructions here: Customizing the Migrations History Table (EF6 onwards)

EF needs Update DB every time I debug my project

I use EF6 and MVC5
I use code-first for my project. and this is my DbContext:
public class ProjectServiceDBContext:DbContext
{
public ProjectServiceIranDBContext()
: base("ProjectServiceDBContext")
{ }
public DbSet<Service> Services { get; set; }
public DbSet<FormPost> FormPosts { get; set; }
public DbSet<Factory> Factories { get; set; }
public DbSet<PictureGallery> PictureGallery { get; set; }
public DbSet<Blog> Blog { get; set; }
public DbSet<Comment> Comment { get; set; }
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new ServiceMapping());
modelBuilder.Configurations.Add(new FactoryMapping());
modelBuilder.Configurations.Add(new FormPostMapping());
modelBuilder.Configurations.Add(new PictureGalleryMapping());
modelBuilder.Configurations.Add(new BlogMapping());
modelBuilder.Configurations.Add(new CommentMapping());
modelBuilder.Configurations.Add(new UserMapping());
}
}
everything was fine before I Added new field to my Blog Model.
I use migrations to update my database . but its works just for one debug , if I stop debugging and start debugging again I get this error for updating database:
The model backing the 'ProjectServiceDBContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
I should use add-migration and update-database every time before debugging
what should I do?
I also delete Migration folder in my solution , and delete my tables in Database and try again and it's not works. also I create new DbContext but still this error is exist.
Try putting this in the constructor for your DbContext:
Database.SetInitializer<ProjectServiceDBContext>(null);
By default, Entity Framework Code-First uses the CreateDatabaseIfNotExists initializer. I think that's what is causing your problem..
If you change you code-first db models, the database needs to be updated to reflect that change. That is when you need to add a new migration and then apply it to ALL databases the application uses.
To apply to a production db, you might want to generate an SQL script of the changes using update-database -script.
Doesn't answer why your context is continually out of date but you could consider using AutomaticMigrations whilst in development.
See section Enabling Migrations

Categories

Resources