Skip to content

[HELP REQUEST] Using Detached in EF Core with an intermediate abstract class in the model #122

@e-projectsrl

Description

@e-projectsrl

I am using Detached Mapper (latest 8.xx version) with Entity Framework Core to do DTO -> Entity mapping.
It has worked quite well in this project so far, except for one thing. In my model, I have the following configuration:

public abstract class MyEntityBase { 
	public MyDiscriminatorEnum Discriminator {get; set;}

   /* Base abstract class for a set of entity types */
}

public abstract class MyEntityWithFooBase: MyEntityBase {
        [Aggregation]
	public Foo {get; set;}
	public Guid FooId {get; set;}
	
	/* Intermediate abstract class for some entity types that require  */
}

public class EntityA: MyEntityBase {
	/* Concrete class that derives from MyEntityBase directly */
}

public class EntityB: MyEntityWithFooBase {
	/* Concrete class that derives from intermediate class MyEntityWithFooBase directly */
}

I'm configuring the model like this:

modelBuilder.Entity<MyEntityBase>()
     .HasDiscriminator(x => x.Discriminator)
     .HasValue<EntityA>(MyDiscriminatorEnum.A)
     .HasValue<EntityB>(MyDiscriminatorEnum.B);            

modelBuilder.Entity<MyEntityWithFooBase>()
     .HasOne(x => x.Foo)
     .WithMany()
     .HasForeignKey(x => x.FooId)
     .OnDelete(DeleteBehavior.Cascade);

The problem arises when I'm trying to map a DTO to a MyEntityBase object, like this:

public void UpdateEntity(MyEntityDao dao)
{
    var ent = dbContext.Map<MyEntityBase>(dao);    
}

Without the intermediate MyEntityWithFooBase class, the code above works as expected. However, with the intermediate class I get the following exception:

Value cannot be null. (Parameter 'key')
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value)
   at Detached.Mappers.EntityFramework.Conventions.EFConventions.Apply(MapperOptions mapperOptions, ClassType typeOptions)
   at Detached.Mappers.Types.Class.ClassTypeFactory.Create(MapperOptions options, Type clrType)
   at Detached.Mappers.MapperOptions.<>c__DisplayClass34_0.<GetType>b__0(Type keyType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Detached.Mappers.MapperOptions.GetType(Type type)
   at Detached.Mappers.Mapper.Map(Object source, Type sourceClrType, Object target, Type targetClrType, IMapContext context)
   at Detached.Mappers.EntityFramework.EFMapper.Map[TEntity](DbContext dbContext, Object entityOrDTO, MapParameters parameters)
   at Detached.Mappers.EntityFramework.MappingDbContextExtensions.Map[TEntity](DbContext dbContext, Object entityOrDTO, MapParameters mapParams)
   at MyProject.UpdateEntity(MyEntityDao dao) in ...

I tried stepping into Detached code, I didn't understand a lot but I think the underlying problem is that Detached is saying that it cannot instantiate an object of type MyEntityWithFooBase, which obviously cannot be done because it is abstract. In other words: it is trying to instantiate the intermediate class instead of the concrete ones.

I'm sure this scenario can be fixed with some configuration, but I didn't find anything relevant in the wiki, can someone help me out?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions