Search code examples
c#.netentity-framework-6odata

Entity Framework 6 : ignore property on basetype for all derived types


I need to ignore the property State on abstract class BaseEntity, but I can't get this to work without using the [NotMappedAttribute], but if I use the attribute the property also gets ignored in the OData API.

I have set up a github project to test this here: https://github.com/nurf3d/EntityFrameworkDerivedTypesIgnoreProperiesTest/tree/master

Inheritance chain:

public abstract class BaseEntity
{
    [Key]
    public int ID { get; set; }

    [Timestamp]
    public byte[] Rowversion { get; set; }

    public State State { get; set; }
}

[Table("Events")]
public abstract class Event : BaseEntity
{
    public int PersonID { get; set; }

    public string EventName { get; set; }

    public virtual Person Person { get; set; }
}

public class DerivedEvent1 : Event
{
    public bool IsDerivedEvent1 { get; set; }
}

public class DerivedEvent2 : Event
{
    public bool IsDerivedEvent2 { get; set; }
}

Attributes:

When using [NotMappedAttribute], the State propery gets ignored for all types correctly and the migration runs fine, but this also removes the property from the OData API, which we don't want.

Since we need the State property within the OData API, we are not using the [NotMappedAttribute], but the fluent configuration.

Fluent configuration:

modelBuilder.Types<BaseEntity>().Configure(clazz => clazz.Ignore(prop => prop.State));

add-migration Initial -Force

Results in this error:

You cannot use Ignore method on the property 'State' on type 'EntityFrameworkIgnoreProperty.Models.DerivedEvent1' because this type inherits from the type 'EntityFrameworkIgnoreProperty.Models.BaseEntity' where this property is mapped. To exclude this property from your model, use NotMappedAttribute or Ignore method on the base type.

I need to get this to work with the Fluent api and I need to do this for all derived types of BaseEntity at once.

In my real project I have 100+ entities, I can't do this by hand for every single entity, especially considering future development.


Solution

  • The problem seems to be related to the fact that Types method body is called for each class inheriting BaseEntity directly or indirectly, which is causing issues with EF inheritance.

    What you could do is to use a filter to apply the configuration only for direct derived types like this:

    modelBuilder.Types<BaseEntity>()
        .Where(t => t.BaseType == typeof(BaseEntity))
        .Configure(clazz => clazz.Ignore(prop => prop.State));