sports
sports

Reputation: 8147

Is it a bad idea that every entity inherits from one base entity?

Would it be there a problem (or maybe its a bad idea), if I make every class inherit from a base class which provides his key/id? This in a codefirst design in Entity Framework

class MyObject
{
[Key]
public int Id { get; set; }
}

class Person : MyObject {...}
class Message : MyObject {...}
class Whatever : MyObject {...}

I want to do this because it is happening a lot that I want two/three classes (for example) to inherit from some base class, and I don't what THAT base class to be responsible of giving the id.

Concrete example, compare this: (actual scenario)

class Recipient
{
[Key]
public int RecipientId { get; set; } // I want to avoid this
public string DisplayName { get; set; }
}

class Person : Recipient {...}
class Group : Recipient {...}

To this: (what i want to achieve)

class MyObject
{
[Key]
public int Id { get; set; }
}

class Recipient : MyObject
{
public string DisplayName { get; set; }
}

class Person : Recipient {...}
class Group : Recipient {...}

Upvotes: 1

Views: 984

Answers (4)

tyler durden
tyler durden

Reputation: 63

in my opinion it creates complications all over. forexample you want to reference userId but alllllll your tables have id because of the super class. well now you have to add stuff like this to your class

@AttributeOverrides(value = { @AttributeOverride(name = "id", column = @Column(name = "passwordTokenId", nullable = false)), @AttributeOverride(name = "name", column = @Column(name = "token", nullable = false)) })

it doesn't end here. what about trying to map relationships in hibernate... you start wondering is this id for class Book or class Person

but its nice when your class is defined as follows

public class Client extends Person public class Broker extends Person

and class Person is defined has String firstName and String lastName .. again the DRY principle

i tried both and i like keep it simple (KISS). like the gentleman above said it embraces DRY but it also violates (KISS).. and i agree with the last gentleman I like what you like :) so follow your instincts

Upvotes: 0

Håkan Edling
Håkan Edling

Reputation: 2753

I know it's been a while since this question was asked by I'll post an answer anyway.

I've done more code first projects than I can count by now and I always end up with an abstract base class for my entities. The reason for this is simple, there's always some fields that you think should be present in all entities, Id of course being the most obvious.

Also, when you add a base class (or interface for that matter), you suddenly allow your DbContext to operate on this abstraction. I almost always add events to this base class (like OnLoad, OnSave, OnDelete) which I leave virtual, then override the SaveChanges method for my DbContext and call the appropriate events for the affected entities.

So my answer is no, there's no harm in adding a base-class to you EF classes. But like some of the above answers stated, if it's mearly for the Id column, then maybe you might as well just repeat that one line (4 with basic comments ;)) in all of your classes.

Upvotes: 5

Gert Arnold
Gert Arnold

Reputation: 109251

I have mixed feelings about it.

Pro

  • It embraces the DRY principle (don't repeat yourself).

Cons

  • It violates the purpose of inheritance, which is to express an "is a" relationship (a Customer "is a" Person). Saying that a Person "is a" base object is meaningless in the business domain. It doesn't express any business logic. Eventually, having a base type may block other inheritance strategies because C# doesn't support multiple inheritance.
  • It mixes business logic and DAL implementation. The fields in the base class have no bearing on the business domain. Having an Id is purely a DAL affair. (Same for values like InsertDateTime that base types are often used for).

I lean to not doing it. If you want your entities to have something in common I'd use an interface. It is considerably more work, I know. And it doesn't seem DRY, but I think the DRY principle should be defined as "don't unnecessarily repeat yourself".

If nevertheless you decide to use a base class, I've found it to be beneficial to make sure it does not become part of the entity model (the model known to entity framework). If it would be, you'd have to make sure EF uses TPC and it would be impossible to use other inheritance models. So, only map the derived types and EF will never know about the base type and never try to implement and inheritance strategy.

Upvotes: 1

NSGaga
NSGaga

Reputation: 14312

The question to me is why you'd want to do that...

I don't see any real reasons to want to 'decouple' base class for the sake of 'ID-ing' alone. All you save is one line of code. Otherwise you won't be using that class in queries (as it really represents nothing), but you'd still have to be careful with 'inheritance' - as your code, with TPC scenario would result in extra table (for all 'non-abstract' classes) - so I'd probably make it abstract just to be sure. Also don't define it as DbSet (that should keep it 'off radar' pretty much, like interface).

And if you already have another base class - that seems like an ideal place for 'ID' - but all this is quite personal.

...in short - I haven't seen any major issues with it (just make it abstract and off DbSet) - though equally I don't see any gains from it. IMO Entities / POCO are C# objects - but afterall present some meaningful underlying data - and I like to see them that way (and also goes for any other class, not just entitiy/POCO).

Upvotes: 1

Related Questions