I have a site. using COde first. My add-migration command producted following code.
public partial class StudentEntity : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.Student",
c => new
{
id = c.Int( nullable: false, identity: true),
name = c.String(),
})
.PrimaryKey(t => t.id);
}
Now I want to deploy my site so when site runs the first time I want the Student table to get generated in DB(SQL server).
Right now when I run the site it does not create any table. How can I do this? I dont want any seed data to initialize with
My db context class
public partial class flagen:DbContext
{
public flagen() : base("name=cf2")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
//old entity
public virtual DbSet<flag> flags { get; set; }
//new entity
public virtual DbSet<Student> students { get; set; }
}
Then I tried to use Context so table get created. It throws error "The model backing the 'flagen' context has changed since the database was created. Consider using Code First Migrations to update the database "
The I added following two lines to dbcontext class
Database.SetInitializer<flagen>(null);
base.OnModelCreating(modelBuilder);
now it says "invalid object name students"
any solution that works?
One solution could be to define a Initializer that will migrate your database to last existing migration you added. Therefore all tables will be created and the Seed method of the Configuration will be executed too - you could use it for seeding data.
With the following example your database will be updated to last existing migration (and therefore creates all tables) on first initialization of the data context. (var dbContext = new MyDatabaseContext())
In my opinion a much cleaner way than to use AutomaticMigrationsEnabled = true that you could check out too. ;)
As mentioned here is an example that will use the MigrateDatabaseToLatestVersion initializer with the defined behavior.
public partial class MyDatabaseContext : DbContext
{
public virtual DbSet<Student> students { get; set; }
public MyDatabaseContext() : base("MyDatabaseContextConnectionString")
{
System.Data.Entity.Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDatabaseContext, Migrations.Configuration>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// here we want to define the entities structure
}
}
You will find some more information about the initializer itself here (MSDN
- MigrateDatabaseToLatestVersion) and here (Entity Framework Tutorial - Code-First Tutorials - Automated Migration) is another example with some more background information and examples.
The answer of this question is to use T4 templates. After searching the web I got the answer that nobody could on SO. Shame...
https://archive.codeplex.com/?p=t4dacfx2tsql
Related
Background
I am using EF Core 3 for an application with a number of POCOs in a DbContext that I want to be created as database tables - no problem here! I use Linq queries to get data here, and life is good.
I also have some raw SQL queries and procedures for some more complex reporting. I've created POCOs for the returned data, and added to the DbContext as a DbSet:
public class FooBarContext : DbContext
{
// ...
public DbSet<FooReport> FooReport { get; set; }
// ...
}
Where FooReport looks like:
public class FooReport
{
[Key]
public int Id { get; set; }
// ...
}
The Problem / Workaround
This creates a migration for creating a new table called FooReport, which isn't what I want.
My workaround right now is to manually remove this action from the Migration that is generated, so that, in essence, I have an empty migration:
public partial class AddFooReport : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
// intentionally clear this out, so the entity isn't created / dropped as a table
// migrationBuilder.CreateTable("FooReport", ... );
}
protected override void Down(MigrationBuilder migrationBuilder)
{
// intentionally clear this out, so the entity isn't created / dropped as a table
// migrationBuilder.DropTable("FooReport");
}
}
Then I'm able to call the procedure like so:
var result = this._fooBarContext.Set<FooReport>(#"[SP_FooReport]")
.FromSqlRaw(sql)
.ToList();
This does work, but seems hacky.
I also (unsuccessfully) tried to solve this problem by adding the NotMapped decorator to the FooReport POCO, but then the query itself fails.
TL;DR; - Can you define a DbSet as an entity that is specifically NOT a table?
In EF Core 3+ simply remove the Key from FooReport to make it a Keyless Entity Type
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<FooReport>().HasNoKey();
//. . .
}
In EF 5 there's an attribute for this too:
[Keyless]
public class FooReport
{
public int Id { get; set; }
// ...
}
You can try adding modelBuilder.Ignore<FooReport>(); call to OnModelCreating method on your DbContext or mark FooReport with NotMapped attribute.
I'm using Entity Framework to insert data into 2 different databases. There are a few columns that are present in one of the databases but not the other. Their data types are not nullable (int and float).
I don't use these columns (when they are present) in my code. Meaning I only insert 0 as the data for them but I can't send null obviously.
Is there a way for me to insert data with ease without creating 2 different versions of my app for these? Ideally I'd like to just have one model with something like an attribute that says insert 0 in this column if it's available.
If your application runs only against one database, then you can just use an IF statement in your OnModelCreating that uses the Fluent API to .Ignore() the missing properties.
public class MyDbContextWithMissingColumns: MyDbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
if (myConfig.UseDatabaseWithoutSomeProperties)
{
modelBuilder.Entity<Foo>().Ignore(f => f.SomeProperty);
}
base.OnModelCreating(modelBuilder);
}
}
If a single instance of your application connects to both databases, then you have to use separate DbContext subtype, as OnModelCreating only runs for the first instance of a DbContext type in an AppDomain.
EG:
public class MyDbContextWithMissingColumns: MyDbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Foo>().Ignore(f => f.SomeProperty);
base.OnModelCreating(modelBuilder);
}
}
In the repository for the database with the restricted fields create the entity:
public class MyClass
{
int MyCommonClassID {get; set;}
string Name {get; set;}
[NotMapped]
string PhoneNumber {get; set;}
}
Where the attribute [NotMapped]. is used that field will not appear in the database but you can use it everywhere else. That wat you determine what gets written at the lowest level and your application doesn't care.
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
I have 2 table which I'm trying to access in MVC, one called Employees and one called Accountable. This is my code: -
public class dbEntity: DbContext
{
public dbEntity(): base("name=dbEntity") {}
public DbSet<Accountable> Accountable { get; set; }
public DbSet<Employees> Employees { get; set; }
}
The problem is the code complains that it can't find the table 'Accountables', I know I can add this line: -
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); }
But then the code complains that it can't find 'Employee'. At the moment it is not practical to rename the tables, is there another way around it?
Thanks
Add a data annotation of your table's name in the database to your context class.
[Table("TableName")]
I have a project built using EF code first. It also uses forms authentication. Until recently the membership database and the application database were being developed separately, but I want to combine them into one database for simplicity.
One of the classes in my code first model is called "Application" so the EF-generated table is called "Applications" which conflicts with a membership table of the same name. This is an example of my current context:
public partial class ExampleContext : DbContext
{
public DbSet<Application> Applications { get; set; }
public DbSet<Status> StatusTypes { get; set; } // notice the name of the property vs the name of the class
}
I thought the table names were based on the names of the properties in the context, because it was generating a table named StatusTypes for all of the Status objects. But if I rename the Applications property to something like MyApplications it is still generating a table named Applications. So clearly it's not just the name of the property and I'm missing something.
My question: how do I get EF to name this table differently?
Couldn't you use the configuration class to do something like this:
public class ApplicationConfiguration : EntityTypeConfiguration<Application>
{
public ClientConfiguration()
{
ToTable("SpecialApplication");
}
}
Then in your context override OnModelCreating:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new ApplicationConfiguration());
}
This should then force your table to be named SpecialApplication and avoid the conflict
By default, Entity framework code first will generate pluralized names for tables when it builds the db from the model classes. You can override the OnModelCreating method of your db context class specify a different name for the table.
public class YourDBCOntext:DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Applications>().ToTable("MYApplications");
}
}
You can do this globally also so that none of the tables will have pluralized names.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTaleNameConvention>();
}
}
I just renamed the class and it worked. Easiest solution for now.