I have an existing DB and I have used the EF 4.1 code first to map my POCO objects to the tables. But I get the this error:
EF 4.1 Error Model compatibility
cannot be checked because the
EdmMetadata type
Eventhough I have added the OnModelCreating method it still gives me the same error:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
}
My POCO and DB Table are exactly identical.
It looks like the issue is that the database exists yet you are trying to create it using EF CodeFirst. If you drop the database, this will most likely run and it will create the database and the table. Here is a link to a person that had this issue and that is how they resolved it:
http://forums.asp.net/t/1673379.aspx/1?Unable+to+generate+Edm+Metadata+table+at+runtime+from+EF+code+first+model
If you wanted to use your existing database (in case you had other data in it), I think you need to modify what Code First expects. Here is a SO article on how to do this:
Entity Framework CTP 4 - Code First Custom Database Initializer
Make sure you read all the posts because even the ones not accepted as the answer have some great information on things you can do.
Related
Grails can automatically create database tables (e.g. in MySQL) based on domain classes.
During debugging, is there a command that will simply print out the SQL statement that would be executed against the database to create the table, based on a domain class?
That is, instead of having Grails actually trying to create the table and generate potential errors (yes, that may include the CREATE TABLE statement).
I would find it useful sometimes to have Grails tell me what SQL CREATE TABLE statement it thinks a domain class maps to.
Use the schema-export command for this.
If you're using Grails 3 you'll need to add the plugin as a classpath dependency in buildscript.dependencies. This is done for you in recent Grails 3 versions but in an earlier release you just need to add it yourself:
buildscript {
...
dependencies {
...
classpath "org.grails.plugins:hibernate:4.3.10.5"
}
}
I have been playing around with Entity Framework and MySql using the Code First approach,
When I run my code against a newly created MySql Server with no databases etc (apart from the defaults) It creates the database and tables according to the classes I have created. My issue is and I don't know if I'm doing this right is, if I make a change to my model class for example add a new property I would expect a new column to be added to that particular table. However this isn't the case instead I'm getting an error
Unknown column: 'Extent1.Email' in 'field list'
I know this is because I have made a change to the class, but I am under the impression that EF would be able to make that change automatically to the database.
I have Installed
EF 6.1.1
MySql.Data 6.9.3
MySql.Data.Entity 6.9.3
All your db initialization takes place in
Interface IDatabaseInitializer(Of In TContext As System.Data.Entity.DbContext)
You can set it in your DbContexts constructor using Entity.Database.SetInitializer() or configure it in your Web.config in <entityFramework><contexts><context><databaseInititalizer>.
To get your new columns in your existing database, you need to either do the necessary migrations (see http://msdn.microsoft.com/en-us/data/JJ591621.aspx) or you drop and recreate the database on every model change (which is what the DropCreateDatabaseIfModelChanges implementation of IDatabaseInitializer does, see http://www.adfa.se/Archive/2013/02/01/database-initializers-in-ef-code-first).
Without further information I recommend you to do the latter.
I am a newbie to wewb2py,is it possible to create at runtime a model of a legacy database, for using DAL with it? I saw that there are some scripts that create the model file, but I do not know whether it is correct to put this file in the model directory of my application, I think not, I did some experiments, I can connect to the database with DAL querying its tables and for every table I can get the definition of the fields, the I tried to define the table with define_table,it works but try to create the table on the database and return an error because the table already exists; this is the relevant part of my code:
conn_string = "mysql://{0}:{1}#{2}/{3}".format(user,pwd,host,db_name)
db = DAL(conn_string)
db.define_table('test1',Field('prova','string'))
it works only the first time, when the table test1 does not exist yet on the database, I do not need to create the tables only work with their data, can you put me on the right way?
db = DAL(conn_string, migrate_enabled=False)
The above will prevent web2py from doing any migrations, including attempting to create any tables.
I know EF checks the EdmMetadata table to determine if the version of model classes is same as database tables.
I want to know exactly how EF can find if the version of a model has changed. In other words, I want to know what does EF compare to the modelhash in the database?
Have a look at this blog post about the EdmMetadata table.
For your question, this is the relevant parts:
The EdmMetadata table is a simple way for Code First to tell if the
model used to create a database is the same model that is now being
used to access the database. As of EF 4.1 the only thing stored in the
table is a single row containing a hash of the SSDL part of the model
used to create the database.
(Geek details: when you look in an EDMX file, the SSDL is the part of
that file that represents the database (store) schema. This means that
the EdmMetadata model hash only changes if the database schema that
would be generated changes; changes to the conceptual model (CSDL) or
the mapping between the conceptual model and the database (MSL) will
not affect the hash.)
I would like to implement a custom database initialization strategy so that I can:
generate the database if not exists
if model change create only new tables
if model change create only new fields without dropping the table and losing the data.
Thanks in advance
You need to implement IDatabaseInitializer interface.
Eg
public class MyInitializer : IDatabaseInitializer<MyDbContext>
{
public void InitializeDatabase(MyDbContext context)
{
//your logic here
}
}
And then set your initializer at your application startup
Database.SetInitializer<ProductCatalog>(new MyInitializer());
Here's an example
You will have to manually execute commands to alter the database.
context.ObjectContext.ExecuteStoreCommand("ALTER TABLE dbo.MyTable ADD NewColumn VARCHAR(20) NULL");
You can use a tool like SQL Compare to script changes.
There is a reason why this doesn't exist yet. It is very complex and moreover IDatabaseInitializer interface is not very prepared for such that (there is no way to make such initialization database agnostic). Your question is "too broad" to be answered to your satisfaction. With your reaction to #Eranga's correct answer you simply expect that somebody will tell you step by step how to do that but we will not - that would mean we will write the initializer for you.
What you need to do what you want?
You must have very good knowledge of SQL Server. You must know how does SQL server store information about database, tables, columns and relations = you must understand sys views and you must know how to query them to get data about current database structure.
You must have very good knowledge of EF. You must know how does EF store mapping information. You must be able to explore metadata get information about expected tables, columns and relations.
Once you have old database description and new database description you must be able to write a code which will correctly explore changes and create SQL DDL commands for changing your database. Even this look like the simplest part of the whole process this is actually the hardest one because there are many other internal rules in SQL server which cannot be violated by your commands. Sometimes you really need to drop table to make your changes and if you don't want to lose data you must first push them to temporary table and after recreating table you must push them back. Sometimes you are doing changes in constraints which can require temporarily turning constrains off, etc. There is good reason why tools which do this on SQL level (comparing two databases) are probably all commercial.
Even ADO.NET team doesn't implemented this and they will not implement it in the future. Instead they are working on something called migrations.
Edit:
That is true that ObjectContext can return you script for database creation - that is exactly what default initializers are using. But how it could help you? Are you going to parse that script to see what changed? Are you going to execute that script in another connection to use the same code as for current database to see its structure?
Yes you can create a new database, move data from the old database to a new one, delete the old one and rename a new one but that is the most stupid solution you can ever imagine and no database administrator will ever allow that. Even this solution still requires analysis of changes to create correct data transfer scripts.
Automatic upgrade is a wrong way. You should always prepare upgrade script manually with help of some tools, test it and after that execute it manually or as part of some installation script / package. You must also backup your database before you are going to do any changes.
The best way to achieve this is probably with migrations:
http://nuget.org/List/Packages/EntityFramework.SqlMigrations
Good blog posts here and here.