Entity Framework Automatic Migrations Existing Database - entity-framework

I am building an ASP.Net MVC4 web application with Entity Framework 5. I had to use an existing sql server database but also wanted to use Code First, so I followed this tutorial http://msdn.microsoft.com/en-us/data/jj200620.aspx
My application uses automatic migrations with Entity Framework.
The version of sql server I was using throughout the development phase was 2008, however, at the last minute I've been told the database needs to work on sql server 2005. I got the database I was using in sql server 2008 setup (exact tables, property names, relationships etc) on sql server 2005. However, with my web config etc setup to point to the sql server 2005 database, when I make a change to my one of my model classes, the automatic migrations don't work.
I get the following error
There is already an object named 'tblcourseprofessionTarget' in the
database.
Can anyone please help?
Thanks.
Apologies if I haven't added enough information.

Folks
The answer to my problem above was helped by this article http://christesene.com/entity-framework-4-3-code-first-with-automatic-migrations/
I had to delete my previous initial migration class, and re-create it.

I had a similar problem.
The cause for me was that the same migration had been run already in the database but under a different MigrationID. I had 201504302005411_InitialCreate but my migration script was called 201505041911076_InitialCreate.
I fixed the issue by renaming the MigrationID in the database to match the one in my code.
I don't quite know how I ended up in the situation but renaming the MigrationID meant the app knew the script had already been run.

if your context is mine: added a new entity class worked on it but, when I tried to migrate it shows this error, try removing that object from db context then run update-database and add that object again and rerun update-database
for example:
public DbSet<CustomizedEmail> CustomizedEmail { get; set; }
public DbSet<KeyWordsForEmail> KeyWordsForEmail { get; set; }
public DbSet<Notice> Notice { get; set; }//remove it>run update-database>
//add again the above entity and rerurn update-database
this works whether you have data or not. in this process you will loose data in that table.

Related

Database first with Identity in .NET Core and Entity Framework Core

I would like to use a Database First approach to managing my database with EF Core, and not just for the initial database creation. I'm using this command to generate my entity models and mapping code:
Scaffold-DbContext "Server=(localdb)\mssqllocaldb;Database=MyDB;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models/Entities -f
Now this works fine. I'm just struggling with identity integration. Currently I have two separate contexts, the one generated by the scaffolding command and an identity context that looks like this:
public class IdentityContext : IdentityDbContext<ApplicationUser> {
public IdentityContext(DbContextOptions<IdentityContext> options)
: base(options) {
}
protected override void OnModelCreating(ModelBuilder builder) {
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}
Both contexts read from the same database and are registered like this:
services.AddDbContext<ApplicationContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<IdentityContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
Is it reasonable to have two separate contexts? Will it cause future problems as I start creating relationships between users and other models? I couldn't find anything in the docs regarding continued use of db-scaffold to generate my entity models and mappings.
Let me know if I can clarify anything.
ORIGINAL CONTEXT
Okay so clearly my original question wasn't any good.
I'd just like some clarification on if my Database First workflow with .NET Core and Entity Framework is the right way. I've read all the articles I can find about using Database First, which all seem to end with: "now you have scaffolded your database so can start using Code First migrations". I want to continue writing my SQL and just keep mapping it to entities.
To manage and update my application I'm using the excellent DbUp project. So I write my scripts, apply them to the database
This appears to be working fine so far. My only problem is integrating identity nicely. Currently I just have two contexts, my application one and an identity one. My application one has also mapped all the identity tables. It is working fine but I'm not sure what will happen going forward as I start linking tables to the user... I believe I did make it work with one context but I had to modify the generated application context each time, removing all the Identity mappings and inheriting from IdentityDbContext (to generate the identity mappings). I could change the schema of the identity tables/my tables and just generate the mappings for my tables, excluding the identity tables. Then I will probably need to manually write mapping properties on ApplicationUser, is that correct?
Basically, I'm not really feeling like Database First is a first class citizen in .NET anymore. Am I just missing something obvious to have this kind of just "work" without modifying generated code? Or am I overthinking this and just need to get on with it?
Apologies for the rambling, one of those days I guess.

Entity Framework not returns data

I'm using EntityFramework 6.1.3. I have generated models from an existing database. Now, when trying to query the database, datacontext returns null. The database appears to be empty.
But the database is not empty as I can connect and query it using LINQPad. When googling the problem I came across a similar situation. In that case the EF generated an empty database on the local server and the solution was to tweak the connection string, although without clear details what exactly should be changed.
However, I'm not sure if that is the case in my situation.
My connection string is pointing to the remote server.
It is not possible that the database was created on the remote server, as we don't have authorisation.
The database was not created on my local machine as I dont even have local sql server installed. And my AppData folder is empty.
Any suggestions?
Generated connection string below
<add name="MAST_DEV" connectionString="metadata=res://*/Models.Mast_DevModel.csdl|res://*/Models.Mast_DevModel.ssdl|res://*/Models.Mast_DevModel.msl;provider=System.Data.SqlClient;provider connection string="data source=xxxxxx;initial catalog=MASTER_DEV;user id=xxxxx;password=xxxxxx;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
I don't really know what I was doing wrong. I have created simple project from scratch , generated models again and it does work fine now. Possibly, previously I selected 'Code first from the database' from Entity Data Model Wizard. Whereas this time 'EF Designer from the database'. Anyway, thanks for trying to help. It was my mistake
This is the exact solution for my problem (the answer is copied from here Entity Framework cant use the DbContext, model being created)
"I see you are using the EDMX with Templates (.tt) for generating the classes. But if you are getting the information from a existing database, the wizard will create a ConnectionString compatible with ObjectContext (metadata informations and provider of entityframework).
The problem is that the connectionstring you are using is for ObjectContext (Database First and Model First). For the DbContext you should use the connectionstring without the metadata informations"

entity framework error there is already an object with that name available in the database

I am using the Entity Framework POCOs to assist with migrating data from a legacy database to a new database. Both databases already exist and the Entity Framework has no part in creating or modifying structure for either. I created a sample database on the migration server and restored it to my local computer sql server (entirely in t_sql, no EF) and my context and its data classes are working fine and returning the data I want. Today I went to the production migration server and when I go to run my first test I get the above referenced error.
All I am doing is reading data, no writing, so this makes no sense to me. EF must be doing something when it hooks up the data context that I can't see. The error is coming from SqlClient.SqlConnection. There is no inner exception, no help link and nothing in the call stack except my method
Any ideas where to start looking?
Pamela
So it turns out the Entity Framework gets mad when the database changes at any point. You need to tell it to ignore the database. I did it by creating this base class for my data contexts
enter code here public class BaseContext<TContext> : DbContext where TContext : DbContext
{
protected BaseContext()
: base("Foxpert.HS.ChangeDetection.VHSContext")
{
Database.SetInitializer<TContext>(null);
Configuration.AutoDetectChangesEnabled = false;
}
}

Entity Framework with existing database

I'm looking to implement entity framework version 4.3.1 in my existing project which don't follow this EF.The database is already developed and is currently used applying ado.net.In this case how do I start with to work on EF, is it Database First,Code first.
Even when a database already exists I still use the Code First approach, mapping the tables using annotations, because the domain is way more organized than on the EDMX file. If there are many tables the visual EDMX can become really useless since the design will be overcrowded with data and connections all over the place.
In two steps you can begin with this approach:
1) Create a domain model class, Customer for example, and map it to your table using data annotations:
[Table("tbl_cust")]
public class Customer
{
[Key]
[Column("cust_id")]
public int CustomerId { get; set; }
[Column("cust_name")]
public string Name { get; set; }
// Add other properties below
}
2) Create a context class deriving from DbContext and set DbSet<T> properties for each model, we have only one in our case so:
public class MyApplicationContext: DbContext
{
public MyApplicationContext() : base("name=ConnectionStringName") { }
public DbSet<Customer> Customers { get; set; }
}
Now anywhere in your code can instantiate the derived DbContext class and make queries using Linq:
var _db = new MyApplicationContext();
var customer = _db.Customers.Where(c => c.CustomerId == 37).FirstOrDefault();
Don't forget to add a reference to EntityFramework assembly using NuGet.
Good Luck.
Since your database already exists the obvious choice is Database first. If the database is designed with common sense it (mostly) works great.
I think the question is if you want to use the EF Designer to visualize your database or not. Since you are looking at EF 4.3.1 (in fact you should be looking at EF5 not 4.3.1 - EF5 is the latest version) I assume you don't care about the designer. In this case you could use EF Power Tools to reverse engineer your database. This will create a set of classes that will match your database. Note that since the database has already been created EF will not be able to detect changes in your classes (as opposed to databases created by Code First when additional information is stored in the database and EF is able to tell whether the model has changed). Make sure to read this blog post - it contains a lot of details you may find helpful to make the decision.
If you care about being able to see your model in the designer you can just use VS to reverse engineer DB. If you use VS2012 you will by default get EF5 and DBContext. The difference from using Code First will be that instead of building the model EF needs based on your classes the model is saved in the the edmx file that is part of your project (and used to generate code for you)

Code First for SQL Server 2005?

My development DB is 2008 R2 which is where Code First generates the local database with DropCreateIfModelChanges.
My method of deploying to production is to generate scripts from local DB, including data and run that in production. This creates all of the tables, including the EdmMetadata table and populates it with the hash.
Works:
Run script in a different 2008 R2 instance, change connection string for the Entity model to point to this production instance, run application.
Does not work:
Run script in a different 2005 instance, change connection string for the Entity model to point to this production instance, run application. I get an error indicating the model has changed.
I think this doesn't work because the DB compatibility version is a part of the hash. thus in production it generates a hash and compares it to the hash stored in the EdmMetadata table. The new hash is different because it is generated against a 2005 DB.
I am guessing I would not have this problem if I was generating a 2005 DB locally and deploying that to a 2005 production instance. However I don't have 2005 installed and would rather not require all the developers to have to install it, when 2008 supports a 2005 compatibility mode already.
How can I force EF to generate a DB in 2005 compatibility mode?
If the only problem is the model compatibility check, then you can disable database initializers for your context when running in the production environment where you presumably don't need to initialize the database anyway. You can do this in code like so:
Database.SetInitializer<MyContext>(null);
But it's probably better to do it in the app.config/web.config for your production application like so:
<entityFramework>
<contexts>
<context type="MyNamespace.MyContext, MyAssembly" disableDatabaseInitialization="true" />
</contexts>
</entityFramework>
You will need to update to EF 4.3 for this syntax--see http://blogs.msdn.com/b/adonet/archive/2012/01/12/ef-4-3-configuration-file-settings.aspx. There is also a way to do it in EF 4.1: See http://blog.oneunicorn.com/2011/03/31/configuring-database-initializers-in-a-config-file/.
You could also try just updating to to EF 4.3 which doesn't use the EdmMetadata table anymore--it uses the __MigrationHistory table instead. This checks for model compatibility in a different way. It may still flag a difference if Code First would have generated a different database for 2005 than it did for 2008, which is occasionally the case.
You could install SQL Server 2005 Express on your dev box. It's free and would match your production environment better.
Finally, if none of the above work and you need to force Code First to generate a 2005 model/database, then you can do that, but it means using lower-level building blocks. First, you'll need to create the DbModelBuilder yourself and call Entity for each of the entity types for which you have a DbSet declared on your context:
var modelBuilder = new DbModelBuilder();
modelBuilder.Entity<User>();
modelBuilder.Entity<Blog>();
You can do other fluent configuration here or use data annotations as normal. OnModelCreating will not be called so don't put fluent calls there--move them here instead.
Once you have a configured DbModelBuilder you'll need to build and compile to get a compiled model that can be passed to DbContext. It is at this stage that you can pass in "2005" as the provider manifest token.
var compiledModel = modelBuilder
.Build(new DbProviderInfo("System.Data.SqlClient", "2005"))
.Compile();
You should now cache this compiled model in your app domain so that you only build and compile it once. (Normally DbContext does this for you when it builds the model, but if you build the model yourself then you need to also do the caching yourself.)
Finally, you will need to pass the compiled model to a constructor of your context every time you need to use it and have that constructor pass the model on to the base constructor.
public class MyContext : DbContext
{
public MyContext(DbCompiledModel model)
: base(model)
{
}
public DbSet<User> Users { get; set; }
public DbSet<Blog> Blogs { get; set; }
}
There are other constructor overloads for passing a name or connection string as well if you need them.