Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Entity Framework Code-first am I required to have the model of my domain anemic?

with Entity Framework Code-First I have to have all properties public to generate database, this mean using Entity Framework Code-First approach I am forced to have an anemic domain mixed with a rich model? Because Properties that need not be public, have to be.

For example:

Using a rich model, this in Entity Framework will not work:

public class Car
{
    private int _actualPosition;

    public void Accelerate()
    {
        this._actualPosition += 10;
    }
}

To work we need to make _actualPosition public:

public class Car
{
    public int ActualPosition { get; set; }

    public void Accelerate()
    {
        this.ActualPosition += 10;
    }
}

Now Entity IMO is ugly, because I have a method that adds + 10 in the property and have it public at the same time, I don't want that property be public.

Another Example:

Imagine I want a relationship many-to-many but with only one way like:

public class User
{
   public long Id { get; set; }

   public string Name { get; set; }

   public IList<Role> Roles { get; set; }
}

public class Role
{
   public long Id { get; set; }

   public string Name { get; set; }
}

How I do a many-to-many relationship with that model? To my knowledge there's no way I'll have to do a two-way relationship:

public class User
{
   public long Id { get; set; }

   public string Name { get; set; }

   public IList<Role> Roles { get; set; }
}

public class Role
{
   public long Id { get; set; }

   public string Name { get; set; }

   public IList<User> Users { get; set; }
}

With this model I'll be able to make many-to-many relationship:

modelBuilder.Entity<User>()
                .HasMany(x => x.Roles)
                .WithMany(y => y.Users);

I'm right? If yes, Entity Framework is not pleasing me.

The "Another Example" work with answer of @Slauma:

modelBuilder.Entity<User>()
            .HasMany(x => x.Roles)
            .WithMany()
            .Map(a =>
            {
                a.MapLeftKey("UserId");
                a.MapRightKey("RoleId");
                a.ToTable("UserRoles");
            });
like image 950
Acaz Souza Avatar asked Aug 25 '11 17:08

Acaz Souza


People also ask

Are Anemic Domain models bad?

Why is Anemic Domain Model harmful? One could say that the Anemic Domain Model is not going along with Object-Oriented Design. The separation of logic into other class is just not correct in OOD approach. But it is not the primary reason why Anemic Domain Model is harmful.

What are approaches to domain modeling in Entity Framework?

In this article I will be describing the three approaches to using Entity Framework (EF)- Model First, Database First and Code First. The Entity Framework provides three separate approaches to work with data models and each one has its own pros and cons.


1 Answers

Your "Another example" is not correct. You are not forced to expose both ends of a relationship as properties in your model classes. In your example you can remove public IList<User> Users { get; set; } from your Role class and define the mapping like so:

modelBuilder.Entity<User>()
            .HasMany(x => x.Roles)
            .WithMany()
            .Map(a =>
            {
                a.MapLeftKey("UserId");
                a.MapRightKey("RoleId");
                a.ToTable("UserRoles");
            });

This is the case also for one-to-many relationships. There is always a parameterless With... overload, WithMany(), WithRequired(), WithOptional(), etc. to define mappings for relationships where not both ends are exposed in the model.

like image 183
Slauma Avatar answered Sep 29 '22 18:09

Slauma