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.
Related
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.
Can a subtype doesn't have any local attributes?
For example, if I have to create subtypes about the phase of a tournament, as GroupStage, Quarter Finals, Semi Finals and Final I'd better create an attribute or a specialization?
Subtypes are used for specialized attributes and/or relationships, so, yes, you can have subtypes that don't have additional attributes. However, if you don't have either specialized attributes or relationships, it's simpler to add an attribute on your main entity set than to create subtypes. Changing an entity from one subtype to another also requires more effort, so try to use subtypes for roles that don't normally change, rather than for states that vary over time.
I have 2 entities in Core Data which have some common properties. I have to show both the entities in a same list view. What will be the best practice to do this? Can I do some inheritance thing and put common properties in base class?
Core Data supports inheritance.
Open your core data model and select the child entity. Make sure the utilities pane is displayed (top right button in Xcode) and select "Show the data model inspector" (right most icon in the utilities pane).
Here you can select a parent entity for your entity. All attributes of the parent will be available in the child entity.
Apple documentation on Core Data inheritance
What will be the best practice to do this?
It depends on what type of entities you need to model. For example, if you have a Cat and a Dog, you should move the attributes in common in a base entity (say Animal or whatever you want). In other words, you should have a reason for doing this, i.e. entities have a sort of relationship each others.
Can I do some inheritance thing and put common properties in base class?
Yes of course. In a model you are allowed to have a sort of inheritance pattern like the following.
where
I would stress two things here.
First, you can make base entity as an Abstract Entity. In this way, you are not allowed to create instances of this entity.
As per the doc.
You can specify that an entity is abstract—that is, that you will not
create any instances of that entity. You typically make an entity
abstract if you have a number of entities that all represent
specializations of (inherit from) a common entity which should not
itself be instantiated. For example, in a drawing application you
might have a Graphic entity that defines attributes for x and y
coordinates, color, and drawing bounds. You never, though, instantiate
a Graphic. Concrete sub-entities of Graphic might be Circle, TextArea, and Line.
Second, under the hood Core Data will create a single table with all the attributes you have inserted. So, if you have a lot attributes, you will have a lot of columns for a table.
I have a MySQL database and would like to have a similar structure in Core Data. I am very new with using Core Data with Xcode. I have a few fundamental questions if I am doing the right thing.
My Mysql DB looks similar to this:
table.caveconditions
visibilityID
percolationID
xxxx
table.visibility
visibilityID
visibilityValue
...and so on. I would then connect the tables using JOINS
Now, I have done the Core Data modeling like this but I am not quite sure if this is the right approach.
Would be great if someone of you could tell me if this is the right way to do it. In the end I would like to use JSON strings to dump the mysql table into core data.
Thanks a lot
Chris
I have created the new schema. Is this right?
It looks good except for all the "xxxID" attributes e.g. caveID. You also need to follow the naming conventions.
You have the same attribute names with (presumably) the same values in two or more entities. This is necessary in SQL for joins but in Core Data, this is handled by objects and relationships.
Each object in Core Data is automatically universally unique. This means when you create a relationship from one object to another, that relationship concrete identifies on specific unique object.
This means you only need an attribute like caveID in the actual entity that caveID designates which in this case is (presumably) the Caves entity. You don't need the attribute in the CavesConditions entity or any other entity that has a relationship to the "Caves" entity.
(If the xxxID were just artifacts of SQL, you don't actually need them at in Core Data unless some external database your app interacts with requires them.)
A good rule of thumb to use is that any particular value should show up on only one side of a relationship and, ideally, only once in the entire data model.
Naming conventions are a little different than SQL. A Core Data entity isn't a table. An entity is more akin to a class. Each entity is supposed to describe a single instance of a managed object. How many of those instances end up in the object graph is irrelevant. Therefore, entity names are singular.
In this case, Caves should be Cave, Countries should be Country and so on.
Relationships are named after the entity they target. It is not immediate obvious but each reciprocal relationship (the default) on the visual data model editor is actually two relationships because there is one relationship description for each side. Each side has the name of the entity targeted. By convention to-one relationships have a singular name and a to-many relationship has a plural name.
So:
Caves.relConditions<-->>CaveConditons.getCave
...would become
Cave.conditons<-->>CaveConditon.cave
The naming conventions are important because Objective-C uses conventions names to generate and search for accessor methods.
CoreData is NOT a database. Remodel your data as simply as you can and in a way that suits how it will be used in your application and do not think about joins or structure based optimization. You do not have control over the backing schema of a CoreData object model. This is the hardest concept you must get over when starting to use CoreData, but once you do, you will be better off.
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.