Last active
March 22, 2023 16:36
-
-
Save MrZander/0bcdd5a9b8b42e862b5b523b0d49002a to your computer and use it in GitHub Desktop.
AutoMapper ProjectTo error repro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using AutoMapper; | |
using Microsoft.EntityFrameworkCore; | |
namespace MapRepro | |
{ | |
internal class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var config = new MapperConfiguration(cfg => | |
{ | |
cfg.AddProfile(new TestProfile()); | |
}); | |
config.AssertConfigurationIsValid(); | |
var mapper = config.CreateMapper(); | |
var context = new ClientContext(new DbContextOptionsBuilder<ClientContext>().UseInMemoryDatabase("Test").Options); | |
SeedContext(context); | |
// Bar -> Baz -> Widgets.FirstOrDefault() | |
// OKAY | |
var resultOkay = mapper.ProjectTo<Models.BarModel>(context.Bars); | |
System.Diagnostics.Debug.Assert(resultOkay.First().MyBaz.FirstWidget.Id == 50); | |
// Foo -> Bar -> Baz -> Widgets.FirstOrDefault() | |
// System.ArgumentException: 'Property 'MapRepro.Entities.Bar Bar' is not defined for type 'MapRepro.Entities.Bar' (Parameter 'property')' | |
var resultNotOkay = mapper.ProjectTo<Models.FooModel>(context.Foos); | |
System.Diagnostics.Debug.Assert(resultNotOkay.First().MyBar.MyBaz.FirstWidget.Id == 50); | |
} | |
static void SeedContext(ClientContext context) | |
{ | |
var testBaz = new Entities.Baz() { Id = 1 }; | |
testBaz.Widgets.Add(new Entities.Widget() { Id = 50 }); | |
testBaz.Widgets.Add(new Entities.Widget() { Id = 60 }); | |
var testBar = new Entities.Bar() { Id = 100 }; | |
testBar.Foos.Add(new Entities.Foo() { Id = 200 }); | |
testBaz.Bars.Add(testBar); | |
context.Bazs.Add(testBaz); | |
context.SaveChanges(); | |
} | |
} | |
class TestProfile : Profile | |
{ | |
public TestProfile() | |
{ | |
CreateMap<Entities.Foo, Models.FooModel>() | |
.ForMember(f => f.MyBar, opts => opts.MapFrom(src => src.Bar)) | |
; | |
CreateMap<Entities.Bar, Models.BarModel>() | |
.ForMember(f => f.MyBaz, opts => opts.MapFrom(src => src.Baz)) | |
; | |
CreateMap<Entities.Baz, Models.BazModel>() | |
.ForMember(f => f.FirstWidget, opts => opts.MapFrom(src => src.Widgets.FirstOrDefault())) | |
; | |
CreateMap<Entities.Widget, Models.WidgetModel>(); | |
} | |
} | |
class ClientContext : DbContext | |
{ | |
public ClientContext() | |
{ | |
} | |
public ClientContext(DbContextOptions<ClientContext> options) | |
: base(options) | |
{ | |
} | |
public virtual DbSet<Entities.Foo> Foos { get; set; } | |
public virtual DbSet<Entities.Bar> Bars { get; set; } | |
public virtual DbSet<Entities.Baz> Bazs { get; set; } | |
public virtual DbSet<Entities.Widget> Widgets { get; set; } | |
} | |
} | |
namespace MapRepro.Entities | |
{ | |
public class Foo | |
{ | |
public int Id { get; set; } | |
public int BarId { get; set; } | |
public virtual Bar Bar { get; set; } | |
} | |
public class Bar | |
{ | |
public Bar() | |
{ | |
Foos = new HashSet<Foo>(); | |
} | |
public int Id { get; set; } | |
public int BazId { get; set; } | |
public virtual Baz Baz { get; set; } | |
public virtual ICollection<Foo> Foos { get; set; } | |
} | |
public class Baz | |
{ | |
public Baz() | |
{ | |
Bars = new HashSet<Bar>(); | |
Widgets = new HashSet<Widget>(); | |
} | |
public int Id { get; set; } | |
public virtual ICollection<Bar> Bars { get; set; } | |
public virtual ICollection<Widget> Widgets { get; set; } | |
} | |
public partial class Widget | |
{ | |
public int Id { get; set; } | |
public int BazId { get; set; } | |
public virtual Baz Baz { get; set; } | |
} | |
} | |
namespace MapRepro.Models | |
{ | |
public class FooModel | |
{ | |
public int Id { get; set; } | |
public int BarId { get; set; } | |
public BarModel MyBar { get; set; } | |
} | |
public class BarModel | |
{ | |
public int Id { get; set; } | |
public int BazId { get; set; } | |
public BazModel MyBaz { get; set; } | |
} | |
public class BazModel | |
{ | |
public int Id { get; set; } | |
public WidgetModel FirstWidget { get; set; } | |
} | |
public class WidgetModel | |
{ | |
public int Id { get; set; } | |
public int BazId { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment