问题
I use entity framework for a fairly simple issue tracking app. I would like to provide the user the capability to extend the "Issue" entity by adding additional properties such as:
- Number fields
- Text fields (simple or rich text)
- Different lists (multiple\ single select)
- Boolean property
I thought of two ways to accomplish the task:
Extendable Database Approach
This is approach is just and idea and i don"t know how to implement using Entity Framework so i would very much like your help. Here is the basic concept:
- Create a table called IssueExtendedFields that will have a record for each field describing it's type and name and maybe other properties.
- Create another table called IssueFieldOptions that will hold a list of options for each "list type field"
- And the final table caled IssueExtendedFieldValues that will hold a Column with a specific naming convention for each custom field created by the user and a foreign key for each issue..
Now i just don't know how to implement the 3rd step because is use entity framework and there are EF entity objects that are generated out of the tables (DB first) so each new column will theoretical have to re-map and recompile the DAL project.
Do you have any other suggestions?
Dictionary Approach
This approach I know how to implement
- Create a table called IssueExtendedFields that will have a record for each field describing it's type and name and maybe other properties.
- Create another table called IssueFieldOptions that will hold a list of options for each "list type field"
- And the final table called IssueExtendedFieldValues that will hold a record for each "Field - Value" pair that is entered into the system
But it suffers from numerous drawbacks (if you see how to over come them please post).
- Every new property the user adds is just another record multiplies the amount of data stored for each entity by X where X is the number of properties, I see big numbers of issues going into the system and creating a separate table that will hold 10 more records for each issue will generate huge queries that will require a lot of memory.
- On top of the foreseen memory problems I will have to create Dynamic "Pivot" like reports and views to allow the user generating reports again the custom properties, and when you deal with huge amount of data the "Pivot" query will take even more time.
回答1:
I know this question is pretty old, but there's nothing to prevent you from building your EF data model at runtime with whatever your database schema is at that particular moment. Since most of your data model is static, the added complexity is localized to whichever entities can change at runtime:
As you add columns to your database at runtime, so too will you need to add properties to your corresponding type. This means your type is constructed at runtime. Potentially you would create a derived type (or implement some interface) at runtime with the additional properties so that your compile-time code would have a reasonable type to work with otherwise. This can be accomplished using Reflection.Emit.
You'll need to dynamically build your EF mappings at runtime whenever your schema changes. You can do this with EF Code First. If your mappings fit normal EF Code First conventions, there's nothing more you need to do here other than to make sure your runtime types are added to the mapping. Otherwise, you'll have to implement code which determines and configures the necessary mappings for your additional properties at runtime.
Any queries which utilize the additional properties will need to be dynamically constructed at runtime. This means building member access expressions to use in your LINQ queries. Similarly, accessing the values of additional properties only known at runtime would require reflection.
You're correct to be wary of your second approach, which is more widely known as Entity-Attribute-Value (EAV) data modeling. There are a number of downsides to this approach, not the least of which are increased joins / query complexity and lack of foreign key support. However, since the EAV model is declared at compile-time, it is arguably easier to implement.
Alternatively, you might consider using another data store specifically for entities which have a flexible schema, such as document databases.
回答2:
so each new column will theoretical have to re-map and recompile the DAL project.
You answered your own question :) EF works with fixed database schema, so first option is not an option anyway.
来源:https://stackoverflow.com/questions/15019705/dynamic-user-extensible-entities-using-entity-framework