I am still new to EF and MVC and how they work together so excuse my ignorance. I have a SQL DB that I generated the MVC Data Model from and I have recently added some fields to a couple tables and now I need to update those changes from my SQL DB into my Model1.edmx.
The issue is that when I went to update the Model from my DB, the update overwrote all of my [Display(Name = "DisplayName")] and [Required] for each field.
So, my question is this: Is there a way to maintain all of my current changes to the Model and just bring in the new fields without overwriting every table in the Model?
Edit: I have tried this: Add data annotations to a class generated by entity framework but to no success. Whenever I regenerate the Model from the database it just overwrites whatever classes I had there. I am creating a public class just like in the example but it gets wiped when I update the Model. Any ideas?
Any help would be awesome! Thanks!
Related
Folks,
After creating a new ASP .NET MVC 4 application, here is what I did:
From the database explorer, deleted all the tables in the default connection.
Edited AccountModels.cs to and added a few more tables.
Updated UsersContext class to reference the new tables:
public class UsersContext : DbCOntext {
...
DbSet<Items> Items {get; set; }
}
Ran the application.
In the debugger, I see that the following line is invoked:
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
However, when I look at the database, only the five tables relevant to SimpleMembershipProvider are getting created. My additional tables are not getting created.
I am wondering if there is some step that I missed.
Thank you in advance for your help.
Regards,
Peter
You need to create another DbContext class for your domain model.
Using the same DbContext, UsersContext will cause you many problems in the future. I had so many problems with that. and turned out, you need a seperate DbContext for your domain model.
Thank you for your help. I eventually figured it out. The default InitializeSimpleMembershipAttribute class is geared to create only the required tables (and columns) for simple membership. You create your own initializer class that inherits from CreateDatabaseIfNotExists<>. Now, you can just delete and recreate an empty database. When you run your application, ALL your tables will automatically get created.
Peter
I am an ASP MVC 3 noobie who has done a few tutorials. Now I'm trying to build a site. All of the tutorials on the microsoft website emphasize the code-first approach: you define your model with code and then create a datacontext and then the entity framework creates/manages the DB based on your code.
I set up an Employees class and a DataBaseContext class that inherits from DbContext. I added a connection string to Web.config connection string that successfully links DataBaseContext to an already existing empty DB on SQL server. EDIT= That was the problem. See my answer below
But when I try to run the Employees controller created thru scaffolding, I get this error
Invalid object name 'dbo.Employees'.
Description: An unhandled exception occurred during the execution of...
Exception Details: System.Data.SqlClient.SqlException: Invalid object name 'dbo.Employees'.
I followed this post SqlException (0x80131904): Invalid object name 'dbo.Categories' and realized that if I create an employees table on the DB, this excpetion goes away (I get a new one saying that the column names are invalid).
But I thought the whole point of MVC 3 is that the framework will make the DB for you based on the code.
Maybe I need a line of code in the Global.asax Application_start() to create the database? Here is my application_start method:
Sub Application_Start()
AreaRegistration.RegisterAllAreas()
RegisterGlobalFilters(GlobalFilters.Filters)
RegisterRoutes(RouteTable.Routes)
End Sub
Here is the code for Employee:
Public Class Employee
Property EmployeeID As Integer
Property First As String
Property Last As String
Property StartDate As DateTime
Property VacationHours As Integer
Property DateOfBirth As DateTime 'in case two employees have the same name
End Class
Here is the code for the DB context:
Imports System.Data.Entity
Public Class DatabaseContext
Inherits DbContext
Public Property Employee As DbSet(Of Employee)
Public Property AnnualLeave As DbSet(Of AnnualLeave)
End Class
What am I missing?
By default EF uses DropCreateDatabaseIfModelChanges<TContext> database initializer. Accordingly to the MSDN:
An implementation of IDatabaseInitializer<TContext> that will delete, recreate, and optionally re-seed the database with data only if the model has changed since the database was created. This is achieved by writing a hash of the store model to the database when it is created and then comparing that hash with one generated from the current model.
Since the database was created manually, EF can't find the hash and decides do not perform any further initialization logic.
You might want to look into this article, same question successfully answered already.
Or it can be this (also resolved successfully)
Answer to your problem is most likely one of the two.
Hope this will help you
Does the name you're specifying for your connection string match the name of your database context?
For example:
Context
var myDbContext = new MyDbContext();
Connection string
<connectionStrings>
<add name="MyDbContext" connectionString="YOUR.CONNECTION.STRING" providerName="System.Data.SqlServer" />
</connectionStrings>
Try and see if this post I wrote about DbContext with MVC works for you: Code-First
Not a lot to be done to get this to work, but there are a few things that are easily missed that will cause a bunch of head aches.
hope this helps
I had already created a database with that name on SQL server. Once I deleted the existing database, the code first framework created the tables for me like it was supposed to. It seems like if the database already exists, the framework won't set up the tables for you. It wants to create the whole DB from scratch.
You were using AdventureWorks Database?
It has it's own schema assigned to the employees table. HumanResources.Employees and not the default dbo.Employees.
Even though I've identified the problem, I don't know the solution to using the database as configured with the HumanResources schema.
Anybody know?
I get an error when trying to delete a record:
InvalidOperationException - The object cannot be deleted because it was not found in the ObjectStateManager.
public ActionResult Delete(CustomerModel customer)
{
db.Customer.Remove(customer);
db.SaveChanges();
return View();
}
Update: I checked in the bebugger, customer is completely empty..And therefore the database isn't able to delete that specific record.
Any ideas why?
Your customer object was not loaded into the DbContext called db (I'm assuming it's a DbContext... not entirely clear from your code).
With Entity Framework, the DbContext you are using has to be aware of an object it is acting on. It looks like you created customer in some manner other than by loading it into db.
You can add it to the DbContext like this:
db.Attach(customer);
Then, proceed to remove it and save your changes.
For more details see
http://blogs.msdn.com/b/adonet/archive/2011/01/29/using-dbcontext-in-ef-feature-ctp5-part-4-add-attach-and-entity-states.aspx
Specifically for your case the paragraph Attaching an existing entity to the context
Update (based on your update)
How did you create customer in the first place? Without that detail, it's just guesswork to understand why it's completely empty.
I want to use MVC 3 and the Entity Framework for my application.
The model will be stored in a different assembly to the MVC app.
The choice I'm making is either to use the EF to generate my entities or to use code first.
With code first, I can decorate members with [Required] etc... But how would I go about adding those attributes if EF has generated entities from the DB?
Having EF generate my entities will save a lot of time, but I want MVC to auto populate the validation depending on how I've decorated my members. Does this make sense? If so, how would I do that?
In that case, MetadataTypeAttribute is used. You can combine it with partial classes to achieve desired results
And by the way, in your place i would do more research when deciding between using Database First and Code First designs. That all is not about saving time when generating entities, there's much more difference between those two approaches. For the time saving purpose, you can use EF Power Tools to generate code first entities from database - simple.
Better than auto generating your entities, I recommend you to use Code First or mapping an existing database to POCO's classes (not generating the entities, just creating them by hand and mapping them to the existing database)
Scottgu wrote about using EF "Code First" with an existing database.
Check this out:
In your model template (file with extension model.tt) you can hack this template for generating decorators, in this example I add the [Required] decorator plus an error message
var simpleProperties = typeMapper.GetSimpleProperties(entity);
if (simpleProperties.Any())
{
foreach (var edmProperty in simpleProperties)
{
if(!edmProperty.Nullable)
{#>
[Required(ErrorMessage="<#=String.Format("The field {0} is required",edmProperty.ToString())#>")]<#
}#>
<#=codeStringGenerator.Property(edmProperty)#><#
}
}
So the result is something like this
[Required(ErrorMessage="The field Id is required")]
public long Id { get; set; }
PS: You can also add the
using System.ComponentModel.DataAnnotations; by editing the template.
Hope this can help you up.
Hey, sorry for my bad english...
Using EF4 code-only, I have created some POCO classes and my database was generated from that. All worked fine, I inserted some data on the tables but now I need to create a new property on one of my classes. If i just create it, the application give me the exception:
{"The model backing the 'TestContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the RecreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data."}
I tried to create manually the field on the table, but it is still complaining... does someone know if there is a way and if so how can I manually update the database schema (i don't want to recreate it because i already have data) to match the model?
It should work if you make sure that your new column match exactly your new property.
For example, if you add a property NewProp
public class MyEntity
{
[Key]
public int Id;
public string PropA;
public int PropB;
public int NewProp;
}
then in your database table MyEntities, you would add a column NewProp of type int not null.
What you can do to check if the column you add is correct, is to rename your database, then let Code-First recreate the database and see what's different between the original and new databases.
EF generates partial classes. So you can add new properties(fields) in another partial class.