Refresh / Recreate an EF object context in code or on application load
Is there a way to do, in code, what is done when creating an object context under add New Item --> Entity Data Model in visual studio?
Lets say for instance I add a new table to my database. Next time I load the application that uses a model of that database, it refreshes the model and creates a default conceptual mapping for that new table automatically.
I would probably be using ESQL to query the database rather than LINQ-To-Entities, so I dont care if there is strongly typed access to the new En开发者_如何学Gotity Sets / Objects.
Also, would this solution require EF code first?
My opinion is that EF with EDMX is not ready for this scenarios. Let me clarify why:
- EDMX is just file used by designer. At runtime you need 3 XML files (SSDL, MSL and CSDL) generated from the EDMX file. These files defines model and they are part of entity connection string.
ObjectContext
is able to work only with entities provided in these files.- Standard approach is single set of these files per connection / context. Once you follow standard approach you have very hard time because adding table mean modifying these XML files (you must use approach where these files are deployed separately - default approach uses these files as resource inside data access assembly).
- I described how to hack EF to allow multiple files per single connection but I don't recommend it.
- If you create separate set of metadata files you will need another context instance to work with new entities (another connection string) and these two context will not know about each other and will not be able to use entities mapped in other one.
- Mapping is only part of the story. Now you need a class which will represent your entity in the application! If you want this "dynamic" behaviour only for development then you are OK but adding table to the model at runtime or on reloading application looks like not a way to go - defining model in ORM tool is for design time not for runtime = you need compiled assembliy with your new entities and you need a code which will use these new entities and reference your new assembly.
DefiningQuery
is just database query - you can use any table present in your database (or even another database) because EF is interested only in result set of this query.
With code first you will have much better development experience. Code first doesn't require EDMX file - it uses mapping defined by code. You will need your application to collect all types derived from EntityTypeConfiguration<>
from predefined (or all referenced) assemblies at bootstrap. All these configurations will be added to DbModelBuilder
in OnModelCreation
when creating the first context instance. You will have a context which can easily use any new entity after restarting application and deploying new assembly with entities. Still you will need code to use this entities. You will have to create DbSets manually instead of exposing them as properties on context class by calling context.Set<EntityType>()
. There are some gotchas when doing this with code first because you must turn off entity model validation and database recreation and you must keep all in sync yourselves.
Still we are discussing scenario where you deploy a new assembly and when application is restarted it will use the assembly. If you require managing tables and "entities" from the application itself then it is not a scenario for direct ORM usage. That is for some metadata models / multi tenant scenarios and it is done completely different way where ORM is used for some general abstract tables and real entity is constructed from metadata stored as abstraction.
Why do you actually want to do it this way?
I don't know a way to make this possible. When you create an entity model you actually create an edmx file which is basically xml. Runtime you can't modify these definition files. From this edmx file, T4 templates generate the context and the .NET classes / entities. As far as I know you can't add class definitions to the model / context at runtime.
Maybe this post also can give some more insight EF retrieve entities from undefined table/view. And else let's hope Ladislav Mrinka or Julie Lerman joins this question ;)
About the EF code first. That won't make any difference because the code first approach is also an edmx file / entity model but then generates the database out of it (instead of generating the entity model from the database) the end result is the same and won't work differently runtime.
Well, the .edmx file is just for visual studio and won't be part of the application. The metadata is stored in three xml files and you can load them at runtime:
http://blogs.msdn.com/b/alexj/archive/2010/01/27/tip-51-how-to-load-ef-metadata-from-an-arbitrary-stream.aspx
You have to map the entities to classes and that is where it becomes ugly. Classes can by generated at runtime with the reflection-api. Or just take a generic class that has many properties like StringProperty1, StringProperty2.
SQL is more appropriate than ESQL for your purpose.
Learning the EF: http://www.testmaster.ch/EntityFramework.test
精彩评论