Mapping not-so-entity-friendly legacy schema to entities

84 Views Asked by At

Okay, I'm really stuck with this one. Basically we've got a legacy table (+ normalization tables) in our database from which true domain entities should be created without altering the table schema. The table looks like this:

# identity table
| Domain (CK) | Group (CK) | Name (CK) | Password |
|-------------|------------|-----------|----------|
| root        |            |           |          |
| root        | group1     |           |          |
|             | group1     | someuser  | XXXXXX   |
|             | group2     |           |          |
|             |            | otheruser | XXXXXX   |

(CK = composite key)

The old application enforced the following rules:

  • If only Domain is set, the entity is a domain which can contain users and groups
  • If only Group is set, the entity is a group which can contain users
  • If Group and Domain is set, the entity is a group within a domain
  • If Name is set, the entity is a user within the respective group or domain (depending on which ones are set)
  • etc. (I hope you get the picture).

What we would like to have in the end would be entities like this (pseudo):

class Domain {
    string Name;
    addUser(user);
    addGroup(group);
}

class Group {
    string Name;
    addUser(user);
}

class User {
    string Name;
    string Password;
}

The only two ways I can think of to resolve this would be either:

  • Creating a base class of all three of the identity classes and creating a second mapping table containing a discriminator. But then: How could I tell EF that the discriminator is in a different table? And how could I enforce the business rules that e.g. an entity within that table having both a Group and a Name is a User?

  • Creating repositories to do the whole job with mapping and stuff and denoting every business rule as pure application logic, but then there would be no way to incorporate EFs cool stuff like lazy loading, automatic mapping, LINQ etc. and we could basically continue using our legacy code. ;)

Specific questions:

  • Is it possible to map a discriminator to a different table in EF?
  • Is it possible to make that discriminator not a value, but rather conditional? (E.g. discriminator for groups => hasValue(Group) && !hasValue(Name)
1

There are 1 best solutions below

0
On BEST ANSWER

It is possible to cheat a bit and not consider these as full blown domain entities. Instead you can treat user management as a separate subdomain with its own bounded context. Isolate the BC from the rest of your domain with an anticorruption layer that translates from the language of this BC to the language of the general domain. Typically, the AC layer will involve mappers from your old, badly designed classes to new Domain, Group and User classes.

I think this is the most sensible way to start benefiting from clean user management entities in your main domain straight away, while keeping options open for a complete makeover of your identity module and database (which should be I guess the ultimate goal).