Is it possible to use a parent table Id instead of child table Id, when child table should put it's Id into another table - class-design

I have this Generalization relation ship between some classes in my class diagram.
FirstClass as a base class that has Name attribute, SecondClass as a derived class that the FirstClass is it's base class and has some other attributes and finally ThirdClass that is a derived class from SecondClass and it has some other attributes too. ThirdClass as an association relation ship with Widget class, 1.*.
I used Joined strategy when I wanted to implement a Data Model from the class diagram. so the FirstTable has their Pk in the SecondTable and the SecondTable has its PK in the ThirdTable.
As you see Third table should has it's PK in Widget class. And there are some costs whenever I want to Join widget table with third table because I need to fetch Name from First Table.
Is it appropriate that I read Id from FirtTable (Actually it's base class) and put it into Widget table?

I think the problem is that if you do, you can't prevent a Widget to be related to an instance of FirstTable that is not an instance of ThirdTable.
Perhaps you could put both the ThirdTable id and the FirstTable id, but in this case you must manage security controls for consistence between both ids.
In both cases, I would advise against. If the join cost is a problem for you, you should consider using a "single table" inheritance strategy.

Related

Entity Framework, Table per Hierarchy, Discriminator column in type table?

I'm trying to see if I can have a discriminator column come from another table, not part of the hierarchy. For example, imagine the following scenario:
PersonTable (PersonID, PersonTypeID, other fields)
EmployeeTable (PersonID, etc)
StudentTable (PersonID, etc)
PersonTypeTable (PersonTypeID, PersonCategoryCode)
I'm creating an abstract class Person, that is inherited into Student and Employee.
I want to have PersonCategoryCode column be the Discriminator column based on which Student or Employee objects are instantiated by EF.
Is this possible? Adding PersonTypeTable to PersonTable mapping's yields errors. PersonTypeID is unfortunately too dynamic to put into static edmx mapping.

Entity Framework Model First and Code First TPH issue

I'm facing two problems by trying to make a model first or code first using TPH concept.
The problem is that I need to use table per hierarchy at three levels, so that:
When I use Model First, the last hierarchy entity (third level) does not saves in database. I create an instance from this entity which inherits an abstract entity, which inherits another abstract entity. The data of two abstract entities are saved, but the last entity not saves. If the inheritance goes at maximum two levels works fine.
If I try to use Code First the problem is that I cannot share attributes with same name, for example: ClassB and ClassC has a property named "Name", and both inherits ClassA. When I map to generate database, I want to create only a sql table called ClassA, but it does not share the column "Name", it creates Name and Name1 columns.
I need to do one of this models works, otherwise I can't use inheritances in my model.
Hope some help!
Thanks

Entity Framework 4 many to many relationship issue

Considering this database:
This is what EF generates:
I think that HeroesItem class, is useless, and there should be a navigation property Items on Hero class and a navigation property Heroes on Item class.
I saw this can be done easily with code first, but how to get it done using database first?
It can be done only if your HeroesItems table does not contain Id column and instead uses IdHero and IdItem as composite primary key. Once you add any additional column to junction table you must map it as entity to have control over that column.

Entity Framework Code First - Table Per Type Inheritance - Insertion Issue?

I'm having an issue inserting an instance of a subclass that inherits from a base class.
Consider the following code snippets from these POCOs:
public abstract class EntityBase<T>
{
private T _id;
[Key]
public T ID
{
// get and set details ommitted.
}
}
public abstract class PersonBase<T> : EntityBase<T>
{
// Details ommited.
}
public class Applicant : PersonBase<int>
{
// Details ommitted for brevity.
}
public class Employee : Applicant {}
Pretty standard inheritance right now. In our system, when an applicant finally becomes an employee, we collect extra data. If not hired, they remain an applicant with a limited set of information.
Now consider the fluent API that sets up the table-per-type inheritance model:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Set up table per type object mapping for the Visitor Hierarchy.
modelBuilder.Entity<Employee>().ToTable("Employees");
}
So far, so good...
If I look at the database this creates, I have a table named Applicants with an Id column of type int, auto-incrementing ID and I have an Employees table with an ID field as the primary key (non auto incrementing).
Basically, the ID field in the Employees table is a foreign key to the Applicants table.
This is what I want. I don't want a record into the Employees table corresponding to the Applicants table until they actually become an Employee.
The problem comes when I try to insert an Employee which comes down to this code:
public void PersistCreationOf(T entity)
{
DataContextFactory.GetDataContext().Set(typeof(T)).Add(entity);
}
The problem: It inserts a brand new applicant and Employee. I hooked it up to the Sql Profiler and looked at both insert queries that come down.
I want to just insert the Employee record with the ID it already has (the foreign key from the Visitors table).
I understand by default it needs to this: Obviously if you create a subclass and insert it, it needs to insert into both tables.
My question is is possible to tell the Framework - the base table already has information - just insert into the child table?
Thanks in advance!
Aside from sending raw SQL commands to insert the Employee minus Applicant properties fragment into the Employees table I believe it's impossible. You can either update or insert an entity. What you want is basically to update the base part of the Employee (or do nothing if nothing changed) and insert the derived part which is not possible.
Imagine what an ORM does: It maps key identities in the database to object identities in memory. Even in memory you couldn't achieve what you want: If you have an object in memory which is a Applicant, it is always an applicant. You cannot magically "upgrade" it to an Employee. You would have to create a new object of type Employee, copy the properties of the Applicant into the base properties of your new Employee and then delete the Applicant. The result is a new object with a new object identity.
I think you have to follow the same procedure in EF. Your Employee will be a new entity with new rows in both Applicant and Employee table and you need to delete the old Applicant. If you have autogenerated keys it will be a new identity with a new ID. (If you hadn't autogenerated keys you could supply the old ID again after deleting the old Applicant, thus "faking" an unchanged identity.) This will of course create big potential trouble if you have references to the old applicant with FK constraints.
Perhaps inheritance is not optimal for this scenario to "upgrade" an applicant into an employee. An optional navigation property (1-to-0...1 relationship) inside of the Applicant which refers to another entity containing the additional properties which make the applicant an employee would solve the problem. This navigation property could be set or not, letting you distinguish between an applicant and applicant which is also an employee. And you would not need to delete and change the ID of the applicant when you make it an employee.
(As said, "I believe". Maybe there is a hidden way, I didn't see.)

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.