13

I have a situation where I have 4-5 very similar classes which I'd like to re-factor to use an abstract base class. The idea behind this would be allow methods which could be used by each class whilst adhering to DRY principles.

The problem I have is that these classes are Entity classes generted from EF4 and each time I try to alter my model it seems to break down.

What's the best/recommended, method to add a base class into my EF model and make the existing classes in the model inherit from this as a base? At the moment I've got no problem adding the base class, giving it an ID property as it seems to require, and then creating the inheritence, but EF then moans about

'Error 3024: Problem in mapping fragments starting at line 18563:Must specify mapping for all key properties (MyBaseType.ID) of the EntitySet MyBaseType.'

In this situation I don't want the base type to be persisted to the DB, purely used as a container for base methods common to all the classes which inherit from it. It feels like I'm missing something simple here but I can't for the life of me see it.

Any ideas on how to add in a base class in this way? Or should I just be adding the base class in code and bypassing the model somehow?

EDIT: As further information, take an example where there are say 3 types, MortageApplicationForm, BankAccountApplicationForm and CreditCardApplication form. They are currently stored in 3 different tables, with a set of different fields. What I'm trying to do, is create a base class of say 'Form' which will have the common fields in it.

At a simple level, say that each table has a primary key ID field called, 'CreditCardFormID', 'BankAccountFormID' etc What I'd like to do it create a base 'Form' class with a property 'ID' which for the case of one table will map to 'CreditCardFormID' and another 'BankAccountFormID'.

I'm happy to do this mapping in partial classes (as I don't want to persist 'ID' to the DB) I simply want to use it in code, so I can write generic methods for things like LoadForm(int ID) without needing to write huge switches for each entity type, or specific methods for each entity type.

3
  • Will a table per type inheritance mapping scenario work for your scenario? Commented Nov 7, 2011 at 16:52
  • Possibly, I will investigate the link in some more detail. At the moment each of the 4-5 classes are there own entity type and defining a common base type in what I'm after. The problem is that they already map to distinct tables in the DB and the existing data will make it tricky to destroy and re-structure the data itself. Commented Nov 7, 2011 at 17:10
  • this seems like a bad idea unless the underlying table structure is changed to match... Commented Nov 7, 2011 at 17:18

2 Answers 2

4

I managed to find a work around for this by rejigging things slightly. Firstly, I did not have the time available to rework the model (which I think would have been the best solution) too much of the system has already been developed with the existing structure to rip it all apart at this point.

The solution so far, has been to create a static helper class to contain business logic which is generic accross in my example, the 3 different account types.

This was coupled with an 'IAccount' interface, allowing the helper class to take an IAccount instance as a parameter (allowing the passing of any particular account type.) This interface contained all the common properties accross the 3-4 concrete classes. It was important to note that in order to create generic methods which I could call on all the classes I was not able to use any other properties specific to the class.

Within the helper methods, I needed to switch my concrete XYZEntities instance to a more generic 'ObjectContext' object and then use the methods such as 'AddObject' rather than 'AddBankAccountForm', 'AddCreditCardForm' etc explicitely. This involved a tiny bit of GetType()'ing to ensure the object was passed to the correct ObjectSet, but seems to work as desired.

Sign up to request clarification or add additional context in comments.

1 Comment

I had a problem where EF did not like the interface. Sorry I can't add more details.
2

There are 3 patterns for this:

  • Table per Class Hierarchy. All concrete types in the inheritance heirarchy are stored in one table.
  • Table per Type. Each type in the inheritance is stored in it's own table.
  • Table per Concrete class. A table for each concrete class but no table for the abstract class.

In your case with the existing tables the Table per Concrete class looks like the best fit.

There is a good description of these options in this book

1 Comment

Yes, as you say, I'm pretty sure that I will need to use a 'Table per concrete class' pattern. The problem I have is that upon adding the base class to my model, it seems to demand an ID field, and then that the ID field is mapped to something. In my example I'd simply like an entity class to inherit from. Which is produced from the auto generated code. I would be happy to code a base class to inherit from without the use of the EF, but since my concrete classes by default will inherit from EntityObject, I cannot force them to inherit from a diffeent base in their respective partials.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.