Dynamically adding new tables to a datacontext or EDM - c#

I know we can add an external XML map file to dynamically alter the table names in a data context. But according to what i have seen on most of the posts, that can be done only if the table structures are same (same columns and primary key).
What i want to know is that, is there a way to dynamically add a new table to the data context when its different from the tables currently in the context.
Or is it possible to achieve this from entity framework?

I'm gonna go a head and say no because the ORM doesn't provide a dynamic run-time model it's a prebuilt static model of the data set that you query against.
Then, all you really need to do to make it dynamic is to rebuilt it as you need it. That will require you to invoke a build when you add new tables or columns but that's not out of the question. And this can be done in a verity of ways.
However, if this is your problem you shouldn't be trying to solve this with an ORM like linq-to-sql. It's was never built for that. I would also recommend entity framework as it has superceeded linq-to-sql in every way (and linq-to-sql is no longer being developed).

Another way would be to use EF 4.1 code first where you can generate and compile code dynamically and load them in your app domain. Well I think you can use dynamic compilation for EF 4.0 as well but Edmx and mappings are complicated.
And it will be new context, you won't be able to change existing context but you may merge in new class library. But this all will have to happen on reflection because you will not have generic types available at compile time for linq.

Related

Is it possible to use Entity Framework and keep object relations in the code and out of the database

I'm having a hard time just defining my situation so please be patient. Either I have a situation that no one blogs about, or I've created a problem in my mind by lack of understanding the concepts.
I have a database which is something of a mess and the DB owner wants to keep it that way. By mess I mean it is not normalized and no relationships defined although they do exist...
I want to use EF, and I want to optimize my code by reducing database calls.
As a simplified example I have two tables with no relationships set like so:
Table: Human
HumanId, HumanName, FavoriteFoodId, LeastFavoriteFoodId, LastFoodEatenId
Table: Food
FoodId, FoodName, FoodProperty1, FoodProperty2
I want to write a single EF database call that will return a human and a full object for each related food item.
First, is it possible to do this?
Second, how?
Boring background information: A super sql developer has written a query that returns 21 tables in 20 milliseconds which contain a total of 1401 columns. This is being turned into an xml document for our front end developer to bind to. I want to change our technique to use objects and thus reduce the amount of hand coding and mapping from fields to xml (not to mention the handling of nulls vs empty strings etc) and create a type safe compile time environment. Unfortunately we are not allowed to change the database or add relationships...
If I understand you correct, it's better for you to use Entity Framework Code First Approach:
You can define your objects (entities) Human and Food
Make relations between them in code even if they don't have foreign keys in DB
Query them usinq linq-to-sql
And yes, you can select all related information in one call.
You can define the relationships in the code with Entity Framework using Fluent API. In your case you might be able to define your entities manually, or use a tool to reverse engineer your EF model from an existing database. There is some support for this built in to Visual Studio, and there are VS extensions like EF Power Tools that offer this capability.
As for making a single call to the database with EF, you would probably need to create a stored procedure or a view that returns all of the information you need. Using the standard setup with lazy-loading enabled, EF will make calls to the database and populate the data as needed.

Entity data inheritance

I'm currently involved in a project where we will present data from an external data source to visitors, but we will also provide meta data for the entities/rewrite some of the original data.
The external data source is a SQL Server database which I've created an .edmx file from and I've created an additional, controllable, SQL Server database with it's own .edmx file. But I'm not comfortable with using two entities for what, in my eyes, is one type of data.
Somehow I would like to merge the two data sources into one, and use only one entity class which I could query. Inheritance in LINQ to Entities would be perfect, but I would prefer no to change the .edmx files manually.
As it is now I have to create wrapper classes and populate them manually with the entity classes, or use multiple database queries to fetch the required data which is a big turn off performance wise.
It feels like it have to exist some sort of work around for these problems I'm facing?
You have two options here.
First you can extend the entity framework class by using partial
classes. It will help you avoiding changes to the generated classes.
Second you can use Entity Framework code first, Which i will
recommend as you will have more control on your entities.

Modifying an ORM model at run time

there has been quite bit of discussion on this topic ( Modifying an Entity Framework Model at Run-Time), but so far I haven't been able to find a nice solution to the problem. We currently have a model built with EF 4.0 and need to allow customers to add custom fields to various tables. We have currently solved the problem with a few generic tables that describe the new properties, but we're finding that the solution is not performing well.
Does anyone know of a good way to dynamically add columns to the database and also update the ORM to reflect that at run-time?
There is no good, nice or manageable way to update EF at runtime to reflect changes in the database. If you really have a database which must change at runtime EF is not good tool for you. EF is strongly typed - every change to database must be reflected not only in mapping but also in entity classes used for loading and persisting data.
Changing entity classes at runtime always goes to area of emitting IL code at runtime. If you pass the process of creating dynamic assembly with dynamic module and dynamic entity types you will face a lot of new challenges:
You will not change your existing types - you will generate a new type every time the user adds or removes some property.
A new type generation brings a new performance cost for rebuilding context's metadata workspace. You must also make sure that this is correctly synchronized if you use it on a server. Another problem is that all existing instances of the old type (before adding or removing property) are now unknown to new instances of EF context and cannot be persisted. If you want to persist them as well you need EF context instances with old metadata workspace as well.
A lot of your code will probably use dynamic instead of real type = no compile time checking. Inheritance and interfaces will not be useful when interacting directly with EF because inheritance must be mapped (you don't want it) and interfaces are not accepted by EF.
The new type is unknown at design time - you cannot use it for design time code and compilation.
EF doesn't like dynamic or ExpandoObject because it uses reflection for mapping -> at runtime your dynamic instance must be correct type otherwise reflection will not work.
How to write queries for dynamic type? The query always starts at generic instance of DbSet or ObjectSet created for concrete type - you must be able to make those instances dynamically as well. Generic argument must be a type mapped to current context - dynamic will not help in this case because it is not a mapped type.
.NET has a nice behavior for this case. It cannot unload assembly. So every time you generate a new type you will have an old time loaded as well.
Do you still want to change EF at runtime? Your current approach is correct one. Simply tune it for better performance but beware that these requirements always come with performance costs - especially with EF.
Alternatively use the last approach mentioned with linked table - fixed number of predefined custom fields directly in the main entity.

View using same type as Table

I have a table that used throughout an app by Entity. I have a view that returns an identical column set, but is actually a union on itself to try to work around some bad normalization (The app is large and partially out of my hands, this part is unavoidable).
Is it possible to have Entity 4 treat a view that is exactly like a table as the same type, so that I can use this view to populate a collection of the same type? This question seems to indicate it is possible in nhibernatem but I can't find anything like it for entity. It would be an extra bonus of the navigation properties could still be used to Include(), but this is not necessary (I can always manually join).
Since EF works on mappings from objects to database entities this is not directly possible. What you need is something like changing the queried database entity dynamically, and AFAIK this is not possible without manually changing the object context.
For sure the EF runtime won't care as long as it can treat the view as if it was completely separate table. The two possible challenges that I forsee are:
Tooling: Our wizard does allow you to select views when doing reverse engineering (i.e. database-first). Definitively if you can use 'code first against an existing database' you can just pretend that the view is just a table, but you won't get any help scripting the database creation or migrations.
Updates: in general you can perform updates for a view setting up store procedure mapping (which is available in the EF Designer from v1 or in Code First starting in EF6). You might also be able to make your view updatable directly or using instead off triggers (see "Updatable Views" here for more details). If I remember correctly the SQL generated by EF to retrieve database generated values (e.g. for identity columns) is not compatible in some cases with instead-off triggers. Yet another alternative is to have your application treat the view as read-only and perform all updates through the actual table, which you would map as a separate entity. Keep in in mind that in-memory entities for the view and the original table will not be kept in sync.
Hope this helps!

WCF DataServices and dynamically changing datasets

from what i've seen so far WCF Data Services are pretty easy to setup when using then in combination with EF.
That's kinda what i'm after out of the box but I also need the ability for the EF model to change at runtime.
I'm building an app where the app users will be able to specify the database structure and then begin populating it ... the relevant UI components needed are then generated with MVC using some clever rule based trickery.
So for example the user will be given a "Create new Object" button, which will let them specify field names.
Once that part is complete the user submits that and it generates a new table in the db.
From there the UI components are generated that allow that table to be managed within the app.
The problem of course is getting that new table in to the EF model without a recompile of the back end data service.
The concept being that this builds the database and the pages required to manage the various parts of it (there's a bigger picture in mind here but i don't want to confuse matters by trying to explain it all).
I'm thinking that maybe EF is not the right tool to use at the moment .. because it needs a strongly typed set of entities in order to work ... that may not be possible in this case.
I'm toying with the idea of passing this service Dynamic objects ... (e.g. objects of type Something : dynamic )
i'd suggest not only that entity framework is not right for this, but neither is a relational database. document database or key-value store would probably be a better fit than trying to create tables on demand to shove this into a relational structure.
WCF Data Services can be used without Entity Framework. Using either the "Reflection Provider" or a custom provider, which you will have to implement (the Reflection provider requires you to have actual .NET classes, which you don't).
Basically, you implement the DataService class and the IServiceProvider interface, which will provide instances of the IDataServiceQueryProvider, IDataServiceMetadataProvider and IDataServiceUpdateProvider. This might involve a lot of work, so be sure that you actually do want to do this.
See http://msdn.microsoft.com/en-us/library/ee960143.aspx for more information.
OMG ...
Apparently this is supported (mostly) out the box with EF 4.2
http://blogs.msdn.com/b/adonet/archive/2011/09/28/ef-4-2-release-candidate-available.aspx
WOW !!!

Categories

Resources