I have tables with the same structure but with a letter prefix of every table.
For example:
A_Company, B_Company, C_Company
There is combo box from which the user can select A, B or C, and then the code saves data into the appropriate table.
How can I do this using EF database-first?
I solved this problem adding a column for code prefix and triggers on my base table company for insert update and delete.
As the other commenters have said, it would be much better to refactor the database to a single table. If you can't do that then the only other thing that I can think of is to have a class which will select the table for you.
I would create a new class which has the same properties as your company tables, and also has the descriminator property. This would then be used as the data source for your ui.
in this class you would have to code manually to draw the data from the correct actual table (and save to it) based on the value of the discriminator. This is fine if you have only a few tables, but as your number of identical tables grows large, this will become more of a headache.
It might be possible to have the base tables all inherit from a virtual base class which would help a bit - you could then create a dictionary which the base class could use to switch the final data source on the fly.
As a final thought have you considered:
1. Creating the master table as suggested by the other commentators as a single table and then having views for each company.
Creating the master table as suggested and then having code to create the individual tables from that one at some point prior to their use?
Related
I have a problem where I have to get the column names and their values from all the Tables in my schema and show that the result in a grid.
I have used the direct approach for this but I have to implement the SqlSiphon structure. For this I have to make getters and setters of each of the column of each Table in the schema which is impossible.
What should I use to get the Column names and their values dynamically from the table.
SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = '" + #Tablename1 + "' AND TABLE_SCHEMA='dbo'"
What will be the best dynamic solution?
And what will be Best to use List , Dictionay or something like 2d Array which will give the column names as well as column values?
A few suggestions:
I'm not completely clear on what you're trying to achieve, but consider using an ORM (Linq2SQL, WEF, NHibernate)
In .NET, a suitable type to represent a database table would be a DataTable
Edit: After a few more re-reads I think I understand what you're asking - you already have a database/schema and you want to automatically create the entity classes needed by SqlSiphon. This is called "database-first" (as opposed to model-first). However, from a brief scan of the SqlSiphon documentation it appears it does not support database-first. Is this why you are trying to put the columns into a grid - to make it easier to manually create the entity classes for SqlSiphon?
Edit2: Note that trying to use an ORM on top of a database whose schema is frequently modified will be problematic. My next guess is that you're trying to figure out how to create an entity class in SqlSiphon which you can use to retrieve database schema information like table columns? I'm still struggling to understand what you're actually asking here - perhaps you can update your question?
Edit3: I think the answer to your question is take a different approach to your design - ORM's like SqlSiphon are not intended to be used to retrieve and modify the database schema itself.
Might be worth taking a step back an comparing against how other people solve similar problems.
Typically, each table on a database represents an entity, and you also have a class per entity, and you may use an ORM system to avoid duplication of work. So, in a typical system, you have a table for customers, and a table for invoices, and a table for invoice lines, etc. and then a class that represents a customer, a class for an invoice, a class for an invoice line, etc. As you later add functionality (and possible columns/properties) you change the classes, rather than just seeing what columns are on the database - you can of course decorate these with XML documentation and get Intelisense goodness.
There are many ORM systems out there, and each have their strengths and weaknesses, but I personally like LINQ to SQL for adding onto an existing data model.
In order to populate Dropdownlists, showing the details rather than id on Gridviews (showing City name instead of Birt city id), etc., sometimes we need to retrieve data at the same time from Master (for ex. Student) and Detail (for ex. City) tables. Could you suggest me which scenarios below is the most suitable? In addition to this I would be appreciated if you suggest other approaches provided that using Entity Framework.
1) I retrieve data from Entity tables and I use relations between master and detail tables. But in that case I need to define these relations on my DbContext and I have to populate dropdownlists by methods. But for displaying data I need to define another methods or etc. For this reason actually I do not like this approach. What do you think for this?
2) Instead of this I can use ModelView as I had used before. But, I think it is not good idea return more tables instead of one table lots of times. In addition to this, I think I need a extra definition for dropdownlist for example in an htl helper. I think it is also not handy.
3) As it is used commonly, I think getting data from entity views (database view) instead of entity table seems to be very useful. With the help of this approach, I can retrieve data from 2 tables and I can easily show this data on dropdownlists and grids without an extra effort. What do you think?
a) On the other hand, if I use a view entity instead of table entity, how can I save this entity to the database (normally I return table entity for creating/editing).
b) If this method is good, in that case I think I need extra entity definitions for the related database views in addition to the tables. For example I have Student, City entities now. But for the database View I need another 3rd entity. Could you give me a usage example for this approach?
BR.
I want to add an extra column, similar to a join to my model based on the ID. Is this possible?
For example:
ProductsModel
ID
DeliveryID
DeliveryModel
DeliveryID
DeliveryDescription
What I'd like to do is add the DeliveryDescription column to my ProductsModel in my .edmx file. I know its possible to add 3 property types (scalar, navigation, complex) are one of these the solution?
No. Default entities must exactly match your tables. There are situations where this is not the true but all involve advanced mapping features like splitting or inheritance. By looking at your tables neither of this is case.
What you are trying to do is equivalent to database view. It is possible in EF by either using QueryView or DefiningQuery. Both will result in new read-only entity type. To use these advanced features you must manually edit EDMX file (and in case of DefiningQuery you cannot use update from database any more because it would delete your changes).
You most probably need this for some data presentation so instead of modifying your mapped entities create a new class outside of EF just for presentation and fill it from entities.
I've got a table of default templates. It's global to all users. If a user has no custom template, I want to pull the default. If a user decides to customize the template it should be saved in a customtemplates table - as opposed to the globaltempaltes table.
the custom table has all the globaltemplates fields plus a userid and an id relating to which global it is replacing.
To flesh this out a bit more, lets say there are 3 templates, and a user wants to customize template 2 only. I would normaly pull the whole globaltemplates table and whatever relates to the user in the customtemplates table. Then, in the class property I'd do something in the get like this:
MyTemplateA
get { return customtemplates.A ?? globaltemplates.A; }
Can I do this using straight ef4/linq without poco?
Would a partial class with some additional properties like the get above work?
Since i'm always editing only the customtemplates table (add/edit/delete) it doesn't matter which version of the template I pull. I guess it could get hairy figuring out if it's an insert or an update.
In my opinion it will not work as you expect because EF closely relates entity to table. You cannot have single entity mapped to two tables except very special situations like splitting or inheritance.
So if you have Template entity it can be mapped only to single table but you have two. What you can do is to use TPC inheritance where Template will be a base entity mapped to GlobalTemplates table and UserTemplate will be derived entity mapped to UserTemplates table. TPC (table per concrete type) is type of inheritance where table for derived entity contains all columns from table for parent entity.
But inheritance still has a few problems for your scenario:
Template is editable - if you want to have it read only you must correctly handle it in your application logic. Any changes to attached Template instance will be saved when you call SaveChanges on the context.
When you load Template you cannot directly convert it to UserTemplate to make it user specific. You must create new instance of UserTemplate and copy properties from Template to the newly created instance.
I'm thinking of building a ecommerce application with an extensible data model using NHibernate and Fluent NHibernate. By having an extensible data model, I have the ability to define a Product entity, and allow a user in the application to extend it with new fields/properties with different data types including custom data types.
Example:
Product can have an addition fields like:
Size - int
Color - string
Price - decimal
Collection of ColoredImage - name, image (e.g. "Red", red.jpg (binary file))
An additional requirement is to be able to filter the products by these additional/extended fields. How should I implement this?
Thanks in advance.
I think this link describes kind of what you want...
http://ayende.com/Blog/archive/2009/04/11/nhibernate-mapping-ltdynamic-componentgt.aspx
More info on dynamic-component:
http://www.mattfreeman.co.uk/2009/01/nhibernate-mapping-with-dynamic-component/
http://bartreyserhove.blogspot.com/2008/02/dynamic-domain-mode-using-nhibernate.html
The idea behind dynamic-component is that you can build your data model by not having a one to one mapping of databse columns with properties. Instead you have only a dictionary property that can contain data from as many properties as you like. This way when you fetch the entity, the dictionary gets the data of all columns configured to belong in there. You can extend the database table's schema to include more columns and that will be reflected to the databse model if you update the mapping file accordingly (manually or though code at application start).
To be honest I do not know you can query such entity using the "attributes" property but if I had to guess I would do an IN statement to it.
One of the options is EAV model (Entity-Attribute-Value).
This model is good to apply if you have a single class in your domain, which table representation would result in a wide table (large number of columns, many null values)
It's originally designed for medical domain, where objects may have thousands of columns (sympthoms).
Basically you have
Entity (Id) (for example your Product table)
Attribute(Id, ColumnName)
Value(EntityId, AttributeId, value)
You can have some additional metadata tables.
Value should better be multiple tables, one for a type.
For example:
ShortStringValue(EntityId, AttributeId, Value nvarchar(50));
LongStringValue(EntityId, AttributeId, Value nvarchar(2048));
MemoValue(EntityId, AttributeId, Value nvarchar(max));
IntValue(EntityId, AttributeId, Value int);
or even a comple type:
ColorComponentsValue(EntityId, AttributeId, R int, G int, B int );
One of the things from my experience is that you should not have EAV for everything. Just have EAV for a single class, Product for example.
If you have to use extensibility for different base classes, let it be a separate set of EAV tables.
Onother thing is that you have to invent a smart materialization strategy for your objects.
Do not pivot these values to a wide row set, pivot just a small number of collumns for your query criteria needs, then return a narrow collection of Value rows for each of the selected objects. Otherwise pivoting would involve massive join.
There are some points to consider:
. Each value takes storage space for foreign keys
. For example row-level locking will behave different for such queries, which may result in performance degradation.
. May result in larger index sizes.
Actually in a shallow hellow world test my EAV solution outperformed it's static counterpart on a 20 column table in a query with 4 columns involved in criteria.
Possible option would be to store all extra fields in an XML structure and use XPath/XQuery to retrieve them from the database.
Each extensible entity in your application will have an XML field, like ExtendedData, which will contain all extra properties.
Another option is to use Non-relationnal Databases which are typically suited for this kind of things.
NOSQL databases(couchDB, mongoDB, cassandre...) let you define dynamically your propretyfields, you could add fields to your product class whenever you want.
I'm searching for similar thing and just found N2 CMS (http://n2cms.com) which implements domain extensibility in quite usable way. It also supports querying over extension fields which is important. The only downside I find out is that it's implemented using HQL so it would take some time to reimplement it to be able to query using QueryOver/Linq, but the main idea and mappings are there. Take a look on ContentItem, DetailCollection, ContentDetail classes, their mappings and QueryBuilder/DetailCriteria.