Object oriented design is all about encapsulation. A class provides methods to manipulate its data and only allows manipulation that keeps the objects’ state correct. That works fine in theory, but in real life objects need to be loaded/materialized from a database and this usually means that property setters must be public. But not with Entity Framework Core! Entity Framework Core uses some reflection magic to access the behind the scenes private properties. So it is now possible to write “real” object oriented entities and persist them to the database.

Adding a normal entity class, without any considerations taken to persistence works perfectly well with EF Core.

public class MyEntity
{
  public MyEntity(string name)
  {
    Name = name;
  }
 
  public int Id { get; private set; }
  public string Name { get; private set; }
 
  public void Rename(string newName)
  {
    Name = newName;
  }
}

There are some restrictions that are in effect though. So it is recommended to make some small adjustments to the entities.

The first restriction is that when using a constructor that takes parameters it must be parameters that EF can bind to a property. Changing the name of the name parameter to something else breaks things:

Unhandled Exception: System.InvalidOperationException: No suitable constructor found for
entity type 'MyEntity'. The following parameters could not be bound to properties of
the entity: 'foo'.

Even though the names match, there is a drawback with having entity framework call a constructor with business logic when loading data from the database. It is better to add a parameterless constructor that EF can use to create objects behind the scenes. It can even be private.

To summarize EF Core is TOTALLY AWESOME. Thanks to this feature it brings back the power of object orientation and encapsulation.

A complete working code example is available in the EfCorePrivate repo on my GitHub Account.

Posted in C# on 2018-06-06 | Tagged Entity Framework Core

Source link

Leave a Reply

Your email address will not be published. Required fields are marked *