views:

185

answers:

1

Hi all,

I have a base class Participants inherited by Artist, Author and TextWriter. I have only one table in the data store: Participants { ID, FirstName, LastName, IsArtist, IsAuthor, IsTextWriter, } The idea is to have a class for all the roles that a participant can have.

I've managed to create the edmx file but when I try to get an Participant (as Artist) that is also an Author I receive the following error:

All objects in the EntitySet 'Participants' must have unique primary keys. However, an instance of type 'Artist' and an instance of type 'Author' both have the same primary key value, 'EntitySet=Participants;ID=1'.

Thank you

+2  A: 

Yes, this is possible. What you're asking for is "table per hierarchy" inheritance. Your table needs to contain any "discriminator column" which identifies the type of each row.

However, no record for one person can have more than one concrete type when materialized (read from the DB), because an object can only have one type. I've written about this issue before:

One of the mental barriers that you have to get over when designing a good object relational mapping is the tendency to think primarily in object oriented terms, or relational terms, whichever suits your personality. A good object relational mapping, though, incorporates both a good object model and a good relational model. For example, let’s say you have a database with a table for People, and related tables for Employees and Customers. A single person might have a record in all three tables. Now, from a strictly relational point of view, you could construct a database VIEW for employees and another one for customers, both of which incorporate information from the People table. When using a one VIEW or the other, you can temporarily think of an individual person as "just" an Employee or "just" a Customer, even though you know that they are both. So someone coming from this worldview might be tempted to do an OO mapping where Employee and Customer are both (direct) subclasses of Person. But this doesn’t work with the data we have; since a single person has both employee and customer records (and since no Person instance can be of the concrete subtype Employee and Customer simultaneously), the OO relationship between Person and Employee needs to be composition rather than inheritance, and similarly for Person and Customer.

If "Bob" is a Participant who is both an Artist and an Author, then he cannot be of type, say, Artist and Author at the same time, unless one is a supertype of the other. Either Artist and Author should have a subtype relationship with the other or you should use aggregation rather than inheritance to relate Participant with Artist and Author. An instance of an object can have only one concrete type; this does not change because you store it to the DB.

Craig Stuntz
I did a table per hierarchy but if for example I have a participant row with the following values:ID:1, FirstName:"Name1",IsArtist:True,IsAuthor:True,IsTextWrite:False When I try to:var artist = ctx.Participants.OfType<Artist>().Where(a => a.ID == 2).FirstOrDefault();var author = ctx.Participants.OfType<Author>().Where(a => a.ID == 2).FirstOrDefault();I receive the error from the question.
black_nm
No entity can have two concrete types. This is basic OOD. If a `Participant` can be both an `Artist` and an `Author`, then either `Artist` and `Author` should have a subtype relationship with the other or you should use aggregation rather than inheritance to relate `Participant` with `Artist` and `Author`. An instance of an object can have only one concrete type; this does not change because you store it to the DB.
Craig Stuntz
All I need is to have Artist, Author classes that are persisted to the same row in the database. The table is like this: Table {ID, FirstName,LastName,IsArtist,IsAuthor} and to be able to query on those classes.
black_nm
You also need an OO and a relational data model which are compatible, and it doesn't sound like you quite have that yet. I'll update the answer with more on this.
Craig Stuntz
In fact I didn't need a OO. I only needed to have some entities in the same row and I think I will use Views for this.
black_nm

related questions