Projection fails but I can do manual projection which fits my goals
public class Parent
{
public int Id { get; set; }
public Child[] Children { get; set; }
public string Name { get; set; }
}
public class Child
{
public int Id { get; set; }
public string Name { get; set; }
}
public class ParentDto
{
public ChildDto[] Children { get; set; }
public string Name { get; set; }
}
public class ChildDto
{
public string Name { get; set; }
}
public class AppDbContext : DbContext
{
public DbSet<Parent> Parents { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Parent>().Property(x => x.Children).HasConversion(
x => JsonConvert.SerializeObject(x, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }),
x => JsonConvert.DeserializeObject<Child[]>(x));
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//optionsBuilder.UseSqlServer(""); //the same exception as for in memory
optionsBuilder.UseInMemoryDatabase("Automapper");
base.OnConfiguring(optionsBuilder);
}
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Parent, ParentDto>(MemberList.Destination);
CreateMap<Child, ChildDto>(MemberList.Destination);
}
}
AutoMapper 9.0.0.0
EF Core 3.1
Newtonsoft.Json 12.0.3
Projection works
Exception
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryExpressionTranslatingExpressionVisitor.VisitParameter(ParameterExpression parameterExpression)
at System.Linq.Expressions.ParameterExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryExpressionTranslatingExpressionVisitor.VisitMember(MemberExpression memberExpression)
at System.Linq.Expressions.MemberExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryExpressionTranslatingExpressionVisitor.Translate(Expression expression)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)
at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.Visit(Expression expression)
at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node)
at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.Visit(Expression expression)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.Visit(Expression expression)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)
at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)
at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryProjectionBindingExpressionVisitor.Translate(InMemoryQueryExpression queryExpression, Expression expression)
at Microsoft.EntityFrameworkCore.InMemory.Query.Internal.InMemoryQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at ConsoleApp3_1.Program.Main(String[] args) in
https://gist.github.com/Boychenko/c004eaf8bf9f9653b1d709b34f120ba2
I think this is better suited for StackOverflow.
@lbargaoanu this wasn't a question. I'm getting the exception for ProjectTo operation.
Isn't it supposed to work?
That looks like an EF Core issue. Check the execution plan. Run that as a LINQ statement, without AM. You should get the same result.
@lbargaoanu have you checked the gist? res1 works fine. I'm expecting that AM doing something like this. I'll check the execution plan a bit later. But according to my understanding, the expression AM builds should be similar to res1
https://gist.github.com/Boychenko/c004eaf8bf9f9653b1d709b34f120ba2#file-automapper-cs-L7
Will it work if you remove the HasConversion(x => JsonConvert.... that; if I understand it correct, store the children as a JSON blob?
@Tasteful works fine for Parents + Children tables and regular parent + child relation using keys
if I understand it correct, store the children as a JSON blob?
Yes, this configuration allows storing a list of objects as a string to a single column
One more addition. This functionality worked for EF Core 2.2 and probably should work for EF Core 3.1 since it works well for regular projection code.