How to read TPH type from a sproc in EF6? - entity-framework-6

ObjectContext.Translate<T> doesn't handle TPH types for T. Is there way to read TPH types from a sproc easily in EF6? Assume the entire table record (along with the discriminator column) is read, with something like "select *" for maintainability in columns are added or changed.
I'm really trying to avoid creating a custom monolithic type that has all properties in the table to read the record, then switch on the discriminator to manually create and map the subtypes by hand. This seems like a huge oversight in the Translate method.
For example, even in EF Core, it seems there are attempt to replicate the Translate method, but I'm not sure the replicated logic handles TPH types: https://github.com/aspnet/EntityFrameworkCore/issues/8127#issuecomment-330973013
There's also a "Materialize" implementation: https://github.com/aspnet/EntityFrameworkCore/issues/8127#issuecomment-440011796 Assuming either of those support TPH, I'm looking for a similar implementation for EF6 to replace the Translate method.

Related

F# recursive types to SQL tables

I'm modeling an application in F# and I encountered a difficulty when trying to construct the database tables for the following recursive type :
type Base =
| Concrete1 of Concrete1
| Concrete2 of Concrete2
and Concrete1 = {
Id : string
Name : string }
and Concrete2 = {
Id : string
Name : string
BaseReference : Base }
The solution I've got for the moment (I've found inspiration here http://www.sqlteam.com/article/implementing-table-inheritance-in-sql-server) is :
I have two concerns with this solution :
There will be rows on the Base table even though that doesn't make sense in my model. But I can live with that.
It seems that queries to find all the information about BaseReference of Concrete2 will be complex since I will have to take into account the recursivity of the type and the different concrete tables. Moreover, adding a new concrete type to the model must modify these queries. Unless of course there is an equivalent to the match F# keyword in SQL.
Am I worrying too much about these concerns? or maybe, is there a better way to model this recursive F# type in SQL tables?
Part 1: Encoding Algrebraic Data Types in Relational Tables
I've struggled with this very thing many times. I finally discovered the key to modeling algebraic data types in relational tables: Check constraints.
With a check constraint, you can use a common table for all members of your polymorphic type yet still enforce the invariant of each member.
Consider the following SQL schema:
CREATE TABLE ConcreteType (
Id TINYINT NOT NULL PRIMARY KEY,
Type VARCHAR(10) NOT NULL
)
INSERT ConcreteType
VALUES
(1,'Concrete1'),
(2,'Concrete2')
CREATE TABLE Base (
Id INT NOT NULL PRIMARY KEY,
Name VARCHAR(100) NOT NULL,
ConcreteTypeId TINYINT NOT NULL,
BaseReferenceId INT NULL)
GO
ALTER TABLE Base
ADD CONSTRAINT FK_Base_ConcreteType
FOREIGN KEY(ConcreteTypeId)
REFERENCES ConcreteType(Id)
ALTER TABLE Base
ADD CONSTRAINT FK_Base_BaseReference
FOREIGN KEY(BaseReferenceId)
REFERENCES Base(Id)
Simple, right?
We've addressed concern #1 of having meaningless data in the table representing the abstract base class by eliminating that table. We've also combined the tables that were used to model each concrete type independently, opting instead to store all Base instances--regardless of their concrete type--in the same table.
As-is, this schema does not constrain the polymorphism of your Base type. As-is, it is possible to insert rows of ConcreteType1 with a non-null BaseReferenceId or rows of ConcereteType2 with a null BaseReferenceId.
There is nothing keeping you from inserting invalid data, so you'd need to be very diligent about your inserts and edits.
This is where the check constraint really shines.
ALTER TABLE Base
ADD CONSTRAINT Base_Enforce_SumType_Properties
CHECK
(
(ConcreteTypeId = 1 AND BaseReferenceId IS NULL)
OR
(ConcreteTypeId = 2 AND BaseReferenceId IS NOT NULL)
)
The check constraint Base_Enforce_SumType_Properties defines the invariants for each concrete type, protecting your data on insert and update. Go ahead and run all the DDL to create the ConcreteType and Base tables in your own database. Then try to insert rows into Base that break the rules described in the check constraint. You can't! Finally, your data model holds together.
To address concern #2: Now that all members of your type are in a single table (with invariants enforced), your queries will be simpler. You don't even need "equivalent to the match F# keyword in SQL". Adding a new concrete type is as simple as inserting a new row into the ConcreteType table, adding any new properties as columns in the Base table, and modifying the constraint to reflect any new invariants.
Part 2: Encoding hierarchical (read: recursive) relationships in SQL Server
Part of concern #2 I think about the complexity of querying across the 'parent-child' relationship that exists between ConcreteType2 and Base. There are many ways to approach this kind of query and to pick one, we'd need a particular use case in mind.
Example use case: We wish to query every single Base instance and assemble an object graph incorporating every row. This is easy; we don't even need a join. We just need a mutable Dictionary<int,Base> with Id used as the key.
It would be a lot to go into here but its something to consider: There is a MSSQL datatype named HierarchyID (docs) that implements the 'materialized path' pattern, allowing easier modeling of hierarchies like yours. You could try using HierarchyID instead of INT on your Base.ID/Base.BaseReferenceID columns.
I hope this helps.

auto generating Inheritance Mapping mvc DB first

Is it possible to define Inheritance Mapping and a Discriminator Property using a BD first approach.
I use the EDMX diagram to define the mapping of tables to object.
I have a DomainEntity Table that contains all my domain entities and they are descriminated by TypeID that is mapped to a DomainEntityTypes table.
If i had full control i would design the mapping this way:
Define an abstarct class DomainEntity
Inherit from the DomainEntity calss to creat concrete entities
Use the Inheritance Mapping Annotation and the IsDiscriminator Annotation over the TypeID
Use an enum to define all possible types (and i wonder what the types table is for from that point)
Could all this be defined in the EDMX file somehow ? or do i need to stop using auto generation and continue with manual mappings?
There is no "auto-generation" of inheritance mapping. When you use database first you simply load tables to your model and it will create entities with relations. Now if you want to have inheritance you must modify the mapping from the designer. Here is a nice description how to set up TPH inheritance in the designer.
You can define base entity for your inheritance hierarchy as abstract. It is property of the entity in the diagram.
You must inherit a new entity for all types you want to use and correctly set up its discriminator value in the mapping.
There are no real annotations - inheritance is a construct available in the ToolBox and discriminator is a condition defined in the mapping.
You will have no enum. Discriminator column will even not be available in your entities because it is already used to define mapping to correct type (there is limitation that each column can be used only once in the mapping so you can use it either for property or for discriminator but not for both). You will have finite set of entities to describe your inheritance hierarchy instead of enum.

Is it difficult to manage iInheriting a client dataset from another?

Say I have a client dataset CDSPerson that acts as a wrapper around a Persons database table. Say I have another table, PersonBenefits, that joins 1:1 back to the Persons table.
Say I wrap a Delphi class around CDSPerson, PersonClass, and another class around CDSPersonBenefits, PersonBenefitsClass, to read and write records. PersonBenefitsClass inherits from PersonClass so it can provide data from both tables. I'd like to be able to write data back to either table through PersonBenefitsClass.
Has anyone developed a clean way to handle the SQL query, provider flags and commit logic in the inherited class so that (a) fields stay aligned with the parent class and (b) both database tables can be updated?
Is there a reference for this that I can't find? Is this just a bad idea? I'm using Delphi 2007.
If you're going to develop a business-object-to-database mapping framework, (commonly known as ORM, Object-Relational Mapper,) you're going to need to put in a bit of architecture to make relationships like this work properly. Here's one way to do it:
PersonClass and BenefitsClass both inherit from BusinessObjectClass. BusinessObjectClass is a base class that contains the general logic to interact with the dataset. It has a list object of some sort that contains a list of relation objects.
Each relation object is a special object that contains either one or a list of BusinessObjectClass descendants, plus extra data describing the foreign-key relationship between the two tables. When BusinessObjectClass does its queries and its updates, it needs to iterate through all its relation objects and have them do their own queries and updates as appropriate.
In your composite object, (PersonWithBenefitsClass,) in the constructor, call inherited and then set up a relation object that describes the related BenefitsClass. Make sure that any inserts of new objects are done in the right order to preserve referential integrity.
That's the basic idea. (One basic idea. There are probably plenty of other ways to do it.) I'll leave the details of exactly how you implement it up to you.

When building a core data app, should I design the data structure as a SQL DB or an OO design?

I've read the manual and saw some tutorial, but still, I do not understand this point.
If I use Core Data in my app, lets say I have an object that one of its properties (column in DB) is a type field. In SQL i would do another table with types and do a many-to-one connection between them.
Now, In the tutorials they say that core data is not SQLite and i should regard it as a representation of an OOP objects.
So, should I do it the same why I would in SQL? types table and a field in the object table that is a foreign key for the types table or should I create a parent entity and inherit from it, creating a new entity (class) for each of the types I need?
SQL DB, as we all know, is a representation of a OOP schema, so I don't understand the benefit of doing it the hard way with inheritance. It is much nicer in my eyes to do it with a types entity, if possible...
Am i wrong about this?
Thank you,
Erez
In my opinion, these are the hard things. You'll always want to return to database designing. It can be better to use a separate 'table', but you can also use subclasses. Maybe you have an Item class, that can have different types. Then you can maybe create the subclasses CarItem, HouseItem... Each representing a certain type of the Item class.

How to map class hierarchy (base class and inherited classes) to a database

I want to create a hierarchical object model in ASP.NET MVC, but I'm not sure what would be the best way to design database for this. I have a Product base class with certain properties like Title, Price, OnHandQty etc. I have several inherited classes like Book, which has extra properties like ISBN number, Author etc. Many of my products will fall under generic (base) Product class, but some products will fall under these derived classes (e.g. Book). I am not sure what is the best methodology to map this to database. Should I create separate tables for each product type (including one for generic product)? Or is there any better way?
Please note that I'm not really asking about OR mapping. I know how to create classes from DB tables using Entity Framework. But in this case I am confused about the database design itself.
If you are going to use Entity Framework then you should check out Inheritance with EF Code First by mortezam. He explains three strategies that can be used for representing an inheritance hierarchy:
Table per Hierarchy (TPH): Enable
polymorphism by denormalizing the
SQL schema, and utilize a type
discriminator column that holds type
information.
Table per Type (TPT): Represent "is
a" (inheritance) relationships as
"has a" (foreign key) relationships.
Table per Concrete class (TPC):
Discard polymorphism and inheritance
relationships completely from the
SQL schema.
The idea (with Code First) is that you define your classes and inheritance and let the framework create the database for you. That way you don't need to worry so much about the database design.
You might also want to think about using an Object Database or one of the NoSQL storage strategies like Mongo DB which work better than relational databases when you have these kind of 'jagged' classes.

Resources