Discriminator Column Type - entity-framework

I've been looking at various Code First examples of TPT (Table Per Type) in Entity Framework.
I have an abstract base class with 4 concrete implementations, all of which share the exact same interface. These are being stored using EF in a single table named after the abstract base class.
What I wish to do is use the EF Discriminator column, but without using the automatic table creation in Code First, instead adding the configuration and mappings manually. Does anyone know if this would be possible and if so, what the type of the Discriminator column is (name, type, length, nullable, etc.) so I can create one manually?
Many thanks.

Related

Using the same entity type for multiple entity sets (Entity FrameWork)

I have a table and a view which share the same columns and I'm trying to add them to EDM. I created an abstract entity type and 2 derived types A and B.
Initially I tried creating 2 entity sets, one for each of the derived types, and proceeded to add the EntitySetMapping (using IsTypeOf per MS MSL specifications for EntityTypeMapping of derived type) but got an error in the .edmx file that each of the types doesn't have an entity set and isn't mapped.
To solve this, I created a single EntitySet with type as the base EntityType (the abstract one) and used 2 EntityTypeMapping children tags, specifying the StoreEntitySet as the table or the view accordingly. This resolved the issue but created a single DbSet<BaseType> and now I cannot retrieve data from the view or the table using DbContext.
Any ideas on how to properly solve this?
Thanks

Entity Framework Table Per Hierarchy restrictions

I have very big table in my Database and a can't modify it.
So i have BaseEntity type for table.
I have several children (entity1, entity2) and i'd like to map each type to same column ("Date") and name properties differently.
Surely i can't move all same column properties to base type cause there is about 100 columns in my super table (it's not my design i've jst need to map it)
So i have 0019 error and is there any way to solve it or EF not for me?
No. TPH requires that each property defined in derived entity is exclusive for that entity (no other entity can map to the same column). This targets more general rule in EF - each column can be mapped only once. So if you need to use some column in more entities it must be defined in parent and must have same name in all child entities.

Entity Framework 4.1 Code First: How is the Discriminator determined?

Currently I have class hierarchy defined with the Code First approach as follows.
E.F. has autogenerated a nvarchar(128) discriminator. It is not a key field.
How does Entity Framework determine what and what Type the discriminator field should be, and is it always the same, i.e. nvarchar? Is the discriminator at all accessible outside the database i.e. from LINQ to Entity?
Discriminator column is by default nvarchar because it stores names of your classes to differ between types - that is the whole point of this column: to allow EF knowing what class instance from your inheritance hierarchy it should create when it loads record from the database.
Discriminator column is not accessible by linq-to-entities. It is only used to map record to correct type.

How to Use inheritance in EF

I am using EF 4.0 , i have one problem
Table structure in DB is:
Table: Setting--->
Name (PK)
GroupBy
DataType
Table: UserSetting-->
SettingName(PK)(FK)
UserName(PK)(FK)
Value
Table: WorkstationSetting-->
SettingName(PK)(FK)
WorkstationName(PK)(FK)
Value
Now i want to make use of inheritance, because WorkstationSetting and UserSetting inherits settings so any suggestion how to achieve inheritance, i tried but i got error like
"Error 39 Error 3003: Problem in mapping fragments starting at line 1621:All the key properties (Settings.Name) of the EntitySet Settings must be mapped to all the key properties (WorkstationSetting.SettingName, WorkstationSetting.WorkstationName) of table WorkstationSetting.
I see you have in UserSetting and WorkstationSetting a composite PK.
If UserSetting and WorkstationSetting are derived from Setting, they should have Name as PK.
Another comment; in general, it's not recommended to use a name or something "meaningful" as PK since it is less scalable and might cause limitations (i.e. max index size). Use instead an int or uniqueidentifier.
I recommend you to introduce a new field which is SettingId which should be added to all three tables. In EF designer, just add the Inheritance.
Look into table per type inheritance. For example look here. It should help you get started. The idea is that you have a table for each concrete type (as you have) and you map it to an object hierarchy.
Maybe your problem is with the keys. How is your mapping defined? Are the associations between the tables defined in the DB?

Access the property used in mapping entity to a table in EFv4

When we have two entities in EFv4 EDM diagram and only one table for both in the database (for instance, having table Documents and entities Invoice and Qoute), table Documents having documentTypeId column as a discriminator and set this column as a discriminator in the EDM (in Table mappings), how do we read the value of this property in our code?
We cannot assign values to it because EF does it for us under the hood (based on what we entered in Table mappings for condition) but somehow I don't get it why we are also not allowed to read it.
Imo this property is already mapped so you can't map it again. It is used to determine type of materialized entity. Why do you need such column. Usually it is enough to use is operator like:
var document = context.Documents.GetById(id);
if (document is Invoice)
{
...
}
If you only need to select subtypes you can use OfType extension method like:
var invoices = context.Documents.OfType<Invoice>().ToList();
You also don't need to set this value when adding new entity because you are adding subtype - Invoice or Quote.
Edit:
As I understand from your comment you don't need this information in query. In such case you don't need to map it. Simply use partial class of your entity and add custom property which will return your string. Sound like stupid solution but actually it would be the easiest one.
Discriminator column should be part of mapping metadata so in case of T4 template generating your entities, it could be possible to update the template so it generate such property for you.
You may want to use a single-table inheritance hierarchy, as described here.
That way, you could have an abstract Document class that includes a DocumentTypeId column. Invoices and Quotes would extend this class, but specify certain DocumentTypeId filters. However, because the original class has a DocumentTypeId column, they would each have that column as well.
Another advantage to this approach is that you could create utility methods that can act on any Document, and you could pass any Invoice or Quote to these methods.