Get Model schema to programmatically create database using a provider that doesn't support CreateDatabase - entity-framework

I'm using the SQLite provider for Entity Framework 5 but it doesn't support CreateDatabase and thus cannot auto create the database. (Code First)
Is there a way I can obtain the Model schema at runtime so that I can create the SQL "CREATE TABLE" command myself?
If not at runtime, some other way to obtain the schema so I know how to create the table properly?
Thanks!

A) As for obtaining the model schema at runtime part
(all are earlier posts of mine)
See this one How I can read EF DbContext metadata programmatically?
And How check by unit test that properties mark as computed in ORM model?
Also this one for a custom initializer Programmatic data transformation in EF5 Code First migration
Having said that...
The problem I see is where and at what point you actually have the data available.
Actually I'm quite sure you won't be able to do that at any time.
Because to be able to extract that info you need to have a DbContext running - so db has to be constructed etc. etc.
In the initializer maybe - but using different ways to get that info - the above is not available.
B)
The other way would be to go the way of implementing a provider, generator etc. (e.g. this post).
That way you should get all that info just at the right time from the EF/CF itself.
However I haven't played with that much.
For more info you can check the EF source code
This is more of a 'gathered info' so far - in case it helps you get anywhere with it. Not really a solution. I'll add some more tomorrow.
EDIT:
To get the real database metadata, look into the other DataSpace, this should get you to the right place...
(note: things tend to get less exact from here - as obviously there isn't the right official support)
var ssSpaceSet = objectContext.MetadataWorkspace.GetItems<EntityContainer>(DataSpace.SSpace).First()
.BaseEntitySets
.First(meta => meta.ElementType.Name == "YourTableName");
If you look up in debugger, Table property should have the real table name.
However, reflection might be required.
How I can read EF DbContext metadata programmatically?
How check by unit test that properties mark as computed in ORM model?
Programmatic data transformation in EF5 Code First migration
Entity Framework MigrationSqlGenerator for SQLite
http://entityframework.codeplex.com/
Entity Framework - Get Table name from the Entity
ef code first: get entity table name without dataannotations
Get Database Table Name from Entity Framework MetaData
http://www.codeproject.com/Articles/350135/Entity-Framework-Get-mapped-table-name-from-an-ent

Related

Development process for Code First Entity Framework and SQL Server Data Tools Database Projects

I have been using Database First Entity Framework (EDMX) and SQL Server Data Tools Database Projects in combination very successfully - change the schema in the database and 'Update Model from Database' to get them into the EDMX. I see though that Entity Framework 7 will be dropping the EDMX format and I am looking for a new process that will allow me to use Code First in Combination with Database Projects.
Lots of my existing development and deployment processes rely on having a database project that contains the schema. This goes in source control is deployed along with the code and is used to update the production database complete with data migration using pre and post deployment scripts. I would be reluctant to drop it.
I would be keen to split one big EDMX into many smaller models as part of this work. This will mean multiple Code First models referencing the same database.
Assuming that I have an existing database and a database project to go with it - I am thinking that I would start by using the following wizard to create an initial set of entity and context classes - I would do this for each of the models.
Add | New Item... | Visual C# Items | Data | ADO.NET Entity Data Model | Code first from database
My problem is - where do I go from there? How do I handle schema changes? As long as I can get the database schema updated, I can use a schema compare operation to get the changes into the project.
These are the options that I am considering.
Make changes in the database and use the wizard from above to regenerate. I guess that I would need to keep any modifications to the entity and/or context classes in partial classes so that they do not get overwritten. Automating this with a list of tables etc to include would be handy. Powershell or T4 Templates maybe? SqlSharpener (suggested by Keith in comments) looks like it might help here. I would also look at disabling all but the checks for database existence and schema compatibility here, as suggested by Steve Green in the comments.
Make changes in code and use migrations to get these changes applied to the database. From what I understand, not having models map cleanly to database schemas (mine don't) might pose problems. I also see some complaints on the net that migrations do not cover all database object types - this was also my experience when I played around with Code First a while back - unique constraints I think were not covered. Has this improved in Entity Framework 7?
Make changes in the database and then use migrations as a kind of comparison between code and the database. See what the differences are and adjust the code to suit. Keep going until there are no differences.
Make changes manually in both code and the database. Obviously, this is not very appealing.
Which of these would be best? Is there anything that I would need to know before trying to implement it? Are there any other, better options?
So the path that we ended up taking was to create some T4 templates that generate both a DbContext and our entities. We provide the entity T4 a list of tables from which to generate entities and have a syntax to indicate that the entity based on one table should inherit from the entity based on another. Custom code goes in partial classes. So our solution looks most like my option 1 from above.
Also, we started out generating fluent configuration in OnModelCreating in the DbContext but have swapped to using attributes on the Entities (where attributes exist - HasPrecision was one that we had to use fluent configuration for). We found that it is more concise and easier to locate the configuration for a property when it is right there decorating that property.

auto update code first from database model, is it possible?

I have code first classes which are generated from my existing db using ADO.NET Entity Data Model. Now I've added some new tables to the database.
I want to know if its possible to create associated code classes from the new db tables without (re)creating the model again from scratch?
Yes it is, if you use Reverse Engineer Code First to do so. It will create POCOs exactly like Code-First, but it will do so based completely on the current database. No .edmx file and no T4 template. Just Code-First.
You should know, by the way, that this (along with regular Code-First) are going to be the only ones allowed in EF7. They are getting rid of many things to try to slim it down, and both Model- and Database-First got the ax (at least, for now). This blog post from Microsoft's ADO.NET blog explains that, along with some other features.

Programmatic data transformation in EF5 Code First migration

Is it possible to do any type of programmatic data transformation in Entity Framework 5 Code First migrations?
There is an Sql() method to execute queries, but it has return type void and I don't see any way to get the results of the queries I perform.
Example
I have table Recipe with one-to-many relationship to Ingredient. For various reasons I want to convert this to a Ingredients JSON string property instead. The only approach I can think of is something like this:
Create new column IngredientsJson
For each recipe, query its ingredients, construct a JSON string programmatically and insert into the new column.
Drop the old table Ingredient.
You should use db 'initializer' for what you want - and/ore 'Seed' of a sort (as to where to inject into the EF flow).
You can > take a look at this post with a customized < initializer - that performas both Db Create... and Migrate. It's not cut and paste solution, but mostly works (it was just a fast go at the problem, you'd need to adjust a bit, it has couple fixes below).
MigrateDatabaseToLatestVersion dose only the migration part - and you need seed-ing exposed - or manually wrap that part (the main point is in 'checks' done for different situations - i.e. when to 'engage' into migration - or seeding).
Migration should go first, and db 'creation' kind of doesn't make much sense, except for seeding.
You override Seed (you created) to put any db handling there - you have the DbContext exposed - and you can also call SqlQuery if needed.
How to create initializer to create and migrate mysql database?

Defining business objects in Entity Framework

Trying to understand Entity Framework. My approach is database first. However I would like to define other entites in the model that is closer to my business objects. I guess I could write queries in the db and include them in the model. But I would also like to define entirely new entities in the model though they would be based on underlying tables in the db. How do I do that - does anyone know a tutorial?
Regards
Bjørn
db Oldtimer, EF Newbie
Database first means that you have existing database and you can either create model by updating from database or manually. You can use wizard to create initial model and modify it manually to define new entities but you must not use update from database any more or some of your changes will be deleted. Also your custom modifications must follow EF mapping rules (for example it is not directly possible to map multiple entities to the same table except some more advanced mapping scenarios like splitting and inheritance) and some of them (custom queries) must be done directly in EDMX source (XML) because designer doesn't support them - this requires more complex knowledge of EF mapping and it will be definitely hard for newbie.
You can check specification of that XML. For entities mapped to custom queries you will have to use DefiningQuery element in SSDL part of EDMX.

Load an .edmx into the DbModelBuilder

I'm planning on using the Entity Framework 4.1 in my next project, but I'm having trouble finding a good way to go about it.
In short, I want to build a multi-tiered application in which the entities will be travelling through web services, and to keep it all as clean as possible I want to use POCO's rather than self tracking entities. Also, there already exists a SQL 2008 database that will be used to base the entities on.
From what I've read so far (from Julie Lerman's article on http://msdn.microsoft.com/nl-nl/magazine/hh148150%28en-us%29.aspx, amongst others), it seems that:
If you use the Database First approach, you get a beautiful .edmx to edit your model in, but you'll always end up with persistence-aware objects rather than POCO's, which is not useful in my situation.
If you use the Code First approach, the "ADO.NET DbContext generator" only partially helps you: it does generate entities from the .edmx, but it doesn't generate the code required to get the foreign keys and cardinality correct. This means that the code will not work out-of-the-box (-edit, not true, see my post below-), you either have to
a) use Data Annotations on your POCO's, which is ugly imo because it pollutes the POCO's with database information and also creates a dependency on the EntityFramework assembly.
b) use the DbModelBuilder passed to DbContext.OnModelCreating to set the correct foreign key, mapping etc. information (i.e. the 'fluent' API). And even though the API may be 'fluent', it's still pretty hard (and probably unmaintainable) to set all this information correctly so that it matches the existing database (see http://sessionfactory.blogspot.com/2011/04/conventions-in-entity-framework-41.html for some examples of this).
I realize that the reason why the "DbModelBuilder-way" requires so much effort is because it was designed to be used the other way around: you're supposed to generate the database from the Entity definitions, not try to tweak all Entities so that they (hopefully) match an already existing database. However, it seems to me that the "DbModelBuilder-way" will, in the end, produce the best result: pure POCO's with no database metadata in them.
Now, having said all this, my question is:
Does anyone know of a way to load an .edmx into the DbModelBuilder, so that the foreign key, column mapping and other information doens't need to be specified by hand through the fluent API?
I think that this would be the best of both worlds, because you can visually edit the mapping like you would in the Database First scenario, and still get clean POCO's because all required metadata is stored in the DbModelBuilder.
Man what are you talking about?
If you use the Database First approach, you get a beautiful .edmx to
edit your model in, but you'll always end up with persistence-aware
objects rather than POCO's, which is not useful in my situation.
That is not true. EDMX can produce almost everything code first can and even many things which code first can't.
If you use the Code First approach, the "ADO.NET DbContext generator"
only partially helps you: it does generate entities from the .edmx,
but it doesn't generate the code required to get the foreign keys and
cardinality correct. This means that the code will not work
out-of-the-box, ...
That is not true. Once you set up EDMX correctly it will create exactly entities you want.
Does anyone know of a way to load an .edmx into the DbModelBuilder
That way is DbContext T4 generator!
Anyway there is one more tool you can check: EF Power Tools CTP1. This tool can create code first mapping from existing database.
Of course every tool creates model which is 1:1 mapping to the database. If you want anything more you must modify the model or mapping manually!
Apparently, there are two ways you can use the generated code from the "ADO.NET DbContext Generator", depending on which type of connection string you use.
If you use an entity connection string, i.e.:
<connectionStrings>
<add name="MyDBEntities" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.;Initial Catalog=MyDB;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
</connectionStrings>
the DbContext will be filled with all the metadata (column mappings, foreign key relations, etc.) from the .edmx. Also, the DbContext's OnModelCreating isn't executed. This is Database First using POCO's, and this is what I wanted to achieve.
What I did wrong was that I used a regular SQL connection string to pass into the DbContext. This causes a totally different type of behaviour: because the DbContext is now empty, it will try to explore all Entity classes and use conventions to generate a database schema for this. Now the OnModelCreating is called, expecting you to tweak this mapping and then generate a database from this.
In short, the solution was to use an entity connection string rather than a SQL connection string.
Read about the T4 POCO generation templates:
Walkthrough: POCO Template for the Entity Framework
POCO Template Code Generation Options
Using the POCO T4 Code Generation Template for Entity Data Models (video screencast with Julie Lerman)
Those T4 code generation templates allow you to use
database-first approach with EDMX model file
but: generate simple POCO (plain-old CLR objects) which have no inheritance from any EF specific class - they're just absolutely plain CLR classes.....
This gives you the best of both worlds - a nice EDMX model and persistence-ignorant POCO classes.