How to persist old data in database while using EF Data Migrations - entity-framework-4

I was thinking that the purpose of EF DataMigrations is to preserve old data while changing the database structure. Do I think right? But when I update the database with migrations all the old data is erased.
Do I make something wrong or maybe it isn't possible to use data migrations in this kind of scenario ?
this is DbContext:
public class CodeFirstContext : DbContext
{
public CodeFirstContext() : base ("ZenRandevuIzle")
{
}
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Takvim> Takvims { get; set; }
public DbSet<Musteri> Musteris { get; set; }
public DbSet<Randevu> Randevus { get; set; }
public DbSet<SeansTuru> SeansTurus { get; set; }
public DbSet<Hizmet> Hizmets { get; set; }
public DbSet<Islem> Islems { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
}
}
this is Global.asax:
Database.SetInitializer<CodeFirstContext>(new CodeFirstContextInit());
this is migration Config:
internal sealed class Configuration : DbMigrationsConfiguration<CodeFirstContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
}

Does the CodeFirstContextInit initialiser drop the database and recreate it (what is its base class?) normally I wouldn't have an initializer when using migrations.

To use EF 4.3 Code First Data Migrations with an existing database you need to create an "empty" migration so that the Migration-History table is created and a baseline can be established.
The Steps outlined in this post should help http://thedatafarm.com/data-access/using-ef-4-3-code-first-migrations-with-an-existing-database

Related

The dbo.ASPNetUser and the other tables like this don't appear in my Server Explorer

I am working in my MVC5 project and I have created a DbContext different to the ApplicationDbContext but it inherits from the same class. I have been developing some parts of my project but now I want to add all the authentication and authorization stuff. But the tables that ASP.NET creates automatically for this purpose don't show up in my Server Explorer although I can work with the sets named Users and Roles of my context. I have searched the reasons of this but I found nothing useful. I hope someone can answer my question and whether it is an important issue or not. I add the code of my DbContext class. Sorry for my English cause I know it is terrible.
namespace GestionPaladares.Models
{
using System;
using System.Data.Entity;
using System.Linq;
using System.Data.Entity.ModelConfiguration.Conventions;
using GestionPaladares.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
public class PaladarContext : IdentityDbContext<ApplicationUser>
{
// Your context has been configured to use a 'CodeFirstDatabaseModel' connection string from your application's
// configuration file (App.config or Web.config). By default, this connection string targets the
// 'GestionPaladares.Models.CodeFirstDatabaseModel' database on your LocalDb instance.
//
// If you wish to target a different database and/or database provider, modify the 'CodeFirstDatabaseModel'
// connection string in the application configuration file.
public PaladarContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
// Add a DbSet for each entity type that you want to include in your model. For more information
// on configuring and using a Code First model, see http://go.microsoft.com/fwlink/?LinkId=390109.
public virtual DbSet<Product> Products { get; set; }
public virtual DbSet<FoodAndDrink> Foods { get; set; }
public virtual DbSet<SoldBill> SoldBills { get; set; }
public virtual DbSet<CostBill> CostBills { get; set; }
public virtual DbSet<Seller> Sellers { get; set; }
public virtual DbSet<Grocer> Grocers { get; set; }
public virtual DbSet<Owner> Owners { get; set; }
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Measure> Measures { get; set; }
public virtual DbSet<Edge> Edges { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Add ApplicationUser in Dbcontext
public DbSet<ApplicationUser> ApplicationUser { get; set; }
For example,
namespace GestionPaladares.Models
{
using System;
using System.Data.Entity;
using System.Linq;
using System.Data.Entity.ModelConfiguration.Conventions;
using GestionPaladares.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
public class PaladarContext : IdentityDbContext<ApplicationUser>
{
// Your context has been configured to use a 'CodeFirstDatabaseModel' connection string from your application's
// configuration file (App.config or Web.config). By default, this connection string targets the
// 'GestionPaladares.Models.CodeFirstDatabaseModel' database on your LocalDb instance.
//
// If you wish to target a different database and/or database provider, modify the 'CodeFirstDatabaseModel'
// connection string in the application configuration file.
public PaladarContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
// Add a DbSet for each entity type that you want to include in your model. For more information
// on configuring and using a Code First model, see http://go.microsoft.com/fwlink/?LinkId=390109.
public virtual DbSet<Product> Products { get; set; }
public virtual DbSet<FoodAndDrink> Foods { get; set; }
public virtual DbSet<SoldBill> SoldBills { get; set; }
public virtual DbSet<CostBill> CostBills { get; set; }
public virtual DbSet<Seller> Sellers { get; set; }
public virtual DbSet<Grocer> Grocers { get; set; }
public virtual DbSet<Owner> Owners { get; set; }
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Measure> Measures { get; set; }
public virtual DbSet<Edge> Edges { get; set; }
public DbSet<ApplicationUser> ApplicationUser { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Since you are using EF, you should first add migration, then do update database from the PM console window. Take a note you have to select the correct project form the list and be sure of the right connection string in your code or appsettings file.
Or, you have to create your own method to call on startup for fixing the database for you.
public static void EnsureDatabaseCreated(IConfiguration configuration)
{
using (var context = new DatabaseContext(configuration.GetConnectionString(GlobalConstants.APP_SETTINGS_CONNECTION_NAME)))
{
context.Database.Migrate();
}
}
public Startup(IConfiguration configuration, IHostingEnvironment environment)
{
EnsureDatabaseCreated(this.configuration);
}
Change the DatabaseContext class name with yours.
Hope this helps.

Mapping View To MVC Code first

I have view in SQL called ViewTest.
In code I have this model
[Table("dbo.ViewTest")]
public class ViewTest
{
public int Id { get; set; }
public int EmployeeID { get; set; }
public string PreferredName { get; set; }
public string EmailPrimaryWork { get; set; }
public string GeoCoverage { get; set; }
public string Role { get; set; }
public bool? LeftEmpFlag { get; set; }
}
In configuration file:
public virtual IDbSet<ViewTest> ViewTests { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new ViewConfiguration());
}
public class ViewConfiguration : EntityTypeConfiguration<ViewTest>
{
public ViewConfiguration()
{
this.HasKey(t => t.Id);
this.ToTable("ViewTest");
}
}
I want to have connection like this one ViewTests.Where(....) ,but when I tried to do like this way I have error There is already an object named 'ViewTest' in the database..This means entity framework try to create new Table and I don`t want this.I want to access this view only!
Well, it is code first so you should probably create your view in code. If that is not possible, then you need to tell EF not to create the table by commenting that line out of the Up() method on the migration. Once you update-database EF will have it in the metadata and you should be good to go.

MVC migration is empty

I've added a simply Product-class (shown below) but when I run add-migration it generates an empty script. I guess this is hard to troubleshoot but any idea as to why this is?
public class Product
{
public int ProductID { get; set; }
[Required]
public string Name { get; set; }
[DataType(DataType.Currency)]
public decimal Price { get; set; }
}
public class ProductDBContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
The migration file looks like this:
public partial class test : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
Have you added the according Class to your DB context?
public System.Data.Entity.DbSet YourDbSetName { get; set; }
Try Clearing out _MigrationHistory (and possible also opening your Project.Data.csproj to manually delete te migrations pending)
I found the answer here: solution

Questions about Metadata

Wanted to get some clarity on something in regards to how we are implementing our Metadata.
Our Breeze Api is not directly tied to SQL Server so we have implemented a custom EFContextProvider and the DbSet below....
public class MetadataDbContext : DbContext
{
public MetadataDbContext()
: base(nameOrConnectionString: "MetadataDb")
{
Database.SetInitializer<MetadataDbContext>(null);
}
public DbSet<Order> Orders { get; set; }
public DbSet<OrderMeter> OrderMeters { get; set; }
public DbSet<OrderDemand> OrderDemand { get; set; }
public DbSet<MeterHistory> MeterHistory { get; set; }
public DbSet<FieldTech> FieldTechs { get; set; }
public DbSet<Dispatcher> Dispatchers { get; set; }
public DbSet<OrderLookupData> LookupData { get; set; }
public DbSet<Organization> Organizations { get; set; }
public DbSet<Location> Locations { get; set; }
public DbSet<Alert> Alert { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
As you can see I am pointing that DbSet at a database called "MetadataDb" which is just an sdf file we deploy with our project. We then override SaveChangesCore in the Context Provider to route our saves to the correct services instead of going direct to Entity Framework. My question is during some testing we noticed that it seemed Breeze was trying to update the sdf file in some cases. It did not appear that the size of the file changed, but just wanted to make sure before we go to production that the sdf file we are pointing the Metadata at does not grow on our server.
Thanks really enjoy using Breeze.
If the only thing that you are using the .sdf file for is to return metadata then Breeze doesn't do anything more than extract the "edmx" from the ObjectContext or DbContext associated with your database. My guess is that just the act of spinning up the context is causing EF to "modify" the "sdf" file. Breeze is not doing anything to touch the database directly.

Mapping EF 4.1 code-first models to database tables

I have been trying the model-first method when designing my application. We usually like to add a prefix to our tables in larger databases so it is easier to find stuff. For example:
sc_ = Shopping cart tables
wb_ = Water billing tables
ea_ = Employment Application tables
The class I have setup looks like this so far.
public class EFDbContext : DbContext
{
public DbSet<Transaction> Transactions { get; set; }
public DbSet<TransactionItem> TransactionItems { get; set; }
public DbSet<Response> Response { get; set; }
}
Web.config (set currently for local database testing):
<add name="EFDbContext" connectionString="Data Source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=database" providerName="System.Data.SqlClient"/>
What do I need to change so that the Transaction object gets linked to the sc_Transactions table? I haven't seen in my searching that clarifies this.
As a second question, do I have to manually create my tables?
You can override the OnModelCreating method from DbContext in your EFDbContext class:
public class EFDbContext : DbContext
{
public DbSet<Transaction> Transactions { get; set; }
public DbSet<TransactionItem> TransactionItems { get; set; }
public DbSet<Response> Response { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Transaction>().MapSingleType().ToTable("someTableNameHere");
}
}
See this post for more info.
You can use System.ComponentModel.DataAnnotations like so:
[Table("tblUser")]
public class User
{
public int ID { get; set; }
public string Name { get; set; }
}
Or with EF 4 you can override the OnModelCreating method to map your tables, which is quite powerful thing as you can map and adjust many things at once.
public class MyContext: DbContext
{
DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().MapSingleType().ToTable("tblUser");
}
}
For more info see:
EF4 CF custom database mapping
EF keynotes from the Build2011 event (custom mappings are at about
15 min or so)

Resources