views:

37

answers:

1

Hi,

I am an experienced .NET developer but new to EF - so please bear with me. I will use an example of a college application to illustrate my problem. I have these user roles:

Lecturer, Student, Administrator.

In my code I envisage working with these entities as distinct classes so e.g. a Lecturer teaches a collection of Students. And work with 'is Student' 'TypeOf' etc.

Each of these entities share lots of common properties/methods e.g. they can all log onto the system and do stuff related to their role.

In EF designer I can create a base entity Person (or User...) and have Lecturer, Student and Administrator all inherit from that.

The difficulty I have is that a Lecturer can be an Administrator - and in fact on occasion a Student can be a Lecturer.

If I were to add other entities such as Employee and Warden then this gets even more of an issue.

I could presumably work with Interfaces so a person could implement ILecturer and IStudent, however I do not see how this fits within EF.

I would like to work within the EF designer if possible and I'm working model-first (coding in C#).

So any help and advice/samples would be very welcome and much appreciated.

Thanks

A: 

Don't make Student and Lecturer inherit from Person. As you say, what if "Bob" was both a student and a lecturer? This happens all the time in real colleges. You said it best yourself: These are roles, not types. A person can have many roles.

As a rule of thumb, avoid inheritance in O/R mapping when it's not strictly necessary (which is almost never). Just as when coding, favor composition over inheritance.

So you could give each Person a property Roles which is a 0..* collection of Roles. Then to get a list of students, you can do:

var students = from p in Context.People
               where p.Roles.Any(r => r.Id = studentRoleId)
               select p;

Or you could have a related Student type with a 0..1 relationship between Person and Student; this would allow you to add additional data for the student, e.g.:

var students = from p in Context.People
               where p.StudentInfo != null
               select new
               {
                   Id = p.Id,
                   Name = p.Name,
                   Grades = p.Student.Grades
               };
Craig Stuntz
Hi Craig, that's very helpful thanks! I was considering a model based on person-role (many to many) with associated profile, so a person who takes a student role also has an associated student profile. Seems to work pretty well. Thanks again.
mvole