0

I want to map a simplified read-only entity (e.g. for UI dropdowns, that need only id and name) to a table that already has full-feature entity mapped.

I have fairly typical mapping configurations using IEntityTypeConfiguration classes that map entities through EntityTypeBuilder<MyFullClass> and EntityTypeBuilder<MySimpleClass>.

I have no control over database, it's a legacy project and I cannot add new SQL views just to solve this code issue.

public class MyFullClassConfiguration : IEntityTypeConfiguration<MyFullClass>
{
    public void Configure(EntityTypeBuilder<MyFullClass> builder)
    {
        builder.ToTable("MyTable");  
        ... all properties mapped


public class MySimpleClassConfiguration : IEntityTypeConfiguration<MySimpleClass>
{
    public void Configure(EntityTypeBuilder<MySimpleClass> builder)
    {
        builder.ToTable("MyTable");  
        ... minimum of required properties mapped

When I run the project, I get an error:

Cannot use table 'MyTable' for entity type 'MySimpleClass' since it is being used for entity type 'MyFullClass' and there is no relationship between their primary keys.

I tried to artificially link both entities, adding one-to-one relation:

b.HasOne<MyFullClass>().WithOne().HasForeignKey<MySimpleClass>(e => e.Id);

This time the project was started normally, I could read and update entities, but when saving a new MyFullClass, EF threw:

The entity of type 'MyFullClass' is sharing the table 'MyTable' with entities of type 'MySimpleClass', but there is no entity of this type with the same key value that has been marked as 'Added'.

This seems so common scenario - to return simplified versions of complex entities for performance and bandwidth reasons, so I was surprised to discover that it's not supported in EF and that they will implement it only in v3, if I'm not mistaken: https://github.com/aspnet/EntityFrameworkCore/issues/15310

How do I solve this in .NET Core 2.2?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
JustAMartin
  • 13,165
  • 18
  • 99
  • 183
  • As far as I undestand you don't need to map it, just write a method which returns a list of your simple objects, context.MyFullClass.AsNoTracking().Select(f => new{f.Id, f.Name}) for example – feihoa Aug 06 '19 at 07:23
  • @feihoa Yes, my first idea was similar, but I'm using generic methods and the database field naming is chaotic - I wouldn't want to write specific `Select`s for every individual case. – JustAMartin Aug 06 '19 at 07:25
  • I guess it's impossible, or you need too much magic. Try to look here:https://stackoverflow.com/questions/49986756/efcore-map-2-entities-to-same-table – feihoa Aug 06 '19 at 07:31
  • Oh, I just found that Automapper supports generating `Select`s - I guess, I'll have to use these for my read-only lightweight entities: http://docs.automapper.org/en/stable/Queryable-Extensions.html# – JustAMartin Aug 06 '19 at 08:17

0 Answers0