EF6自动映射器继承/抽象类错误 [英] EF6 Automapper Inheritance/Abstract Class Errors

查看:77
本文介绍了EF6自动映射器继承/抽象类错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有AutoMapper的Entity Framework 6构建.NET Web API,以将实体映射到DTO.当我尝试引入带有抽象基类的TPH(每个层次结构的表)时,我遇到了一个非常漫长且非常无用的错误(至少对我而言).错误如下,我不确定实际的错误是什么.我尝试了Google的各个部分,但都没有成功.

I'm building a .NET Web API using Entity Framework 6 with AutoMapper to map entities to DTOs. When I try to introduce an TPH (table per hierarchy) with an abstract base class, I get a very long and very useless (to me at least) error. The error is below, I'm not sure what the actual error is. I've tried Googling various sections of it to no avail.

这是我的映射:

        Mapper.CreateMap<ParentClass, ParentClassDTO>()
            .Include<ClassA, ClassADTO>()
            .Include<ClassB, ClassBDTO>();

        Mapper.CreateMap<ClassA, ClassADTO>();
        Mapper.CreateMap<ClassB, ClassBDTO>();

如果我从ParentClass中删除了abstract,该错误消失了,但是AutoMapper不使用子DTO类,它仅使用ParentClassDTO.如果我一起删除了所有映射,只是通过API返回了实体,则不会出现错误,一切都会按预期进行.

If I remove abstract from the ParentClass, the error goes away but then AutoMapper does not use the child DTO classes, it only uses the ParentClassDTO. If I remove the mapping all together and just return the entities through the API, there are no errors and everything works as expected.

我什至不知道从哪里开始出现以下错误,如何开始调试(在调试模式下运行的Web API仍仅将此错误输出到屏幕上)或导致该错误的原因.我已尽可能简化了代码,并尝试了其他各种方法,但似乎无法解决该问题.

I don't even know where to start with the error below, how to start debugging it (web API running in debug mode still just outputs this error to screen), or what is responsible for the error. I've simplified my code as much as possible and tried other various things, but can't seem to get around this issue.

此特定映射是另一个DTO类中的一个集合,我正在创建该类以从Web API返回IQueryable<AnotherClassDTO>:

This specific mapping is a collection within another DTO class, which I am creating to return a IQueryable<AnotherClassDTO> from a Web API:

return db.AnotherClass.Project().To<AnotherClassDTO>();

OtherClassDTO(一个包含抽象集合的单独类)的设置如下:

The AnotherClassDTO (a separate class which contains the abstract collection) is setup like this:

public class AnotherClassDTO
{
    public IEnumerable<ParentClassDTO> Elements;
}

错误消息:

> {"message":"An error has occurred.","exceptionMessage":"The
> 'ObjectContent`1' type failed to serialize the response body for
> content type 'text/html;
> charset=utf-8'.","exceptionType":"System.InvalidOperationException","stackTrace":null,"innerException":{"message":"An
> error has occurred.","exceptionMessage":"Exception has been thrown by
> the target of an
> invocation.","exceptionType":"System.Reflection.TargetInvocationException","stackTrace":"
> at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[]
> arguments, Signature sig, Boolean constructor)\r\n at
> System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj,
> Object[] parameters, Object[] arguments)\r\n at
> System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags
> invokeAttr, Binder binder, Object[] parameters, CultureInfo
> culture)\r\n at System.Reflection.MethodBase.Invoke(Object obj,
> Object[] parameters)\r\n at
> System.Data.Entity.Core.Common.Internal.Materialization.Translator.TranslateColumnMap(Translator
> translator, Type elementType, ColumnMap columnMap, MetadataWorkspace
> workspace, SpanIndex spanIndex, MergeOption mergeOption, Boolean
> streaming, Boolean valueLayer)\r\n at
> System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext
> context, DbQueryCommandTree tree, Type elementType, MergeOption
> mergeOption, Boolean streaming, Span span, IEnumerable`1
> compiledQueryParameters, AliasGenerator aliasGenerator)\r\n at
> System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1
> forMergeOption)\r\n at
> System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.b__6()\r\n
> at
> System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1
> func, IDbExecutionStrategy executionStrategy, Boolean
> startLocalTransaction, Boolean releaseConnectionOnSuccess)\r\n at
> System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.b__5()\r\n
> at
> System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1
> operation)\r\n at
> System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1
> forMergeOption)\r\n at
> System.Data.Entity.Core.Objects.ObjectQuery`1..GetEnumerator>b__0()\r\n
> at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()\r\n at
> Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter
> writer, IEnumerable values, JsonArrayContract contract, JsonProperty
> member, JsonContainerContract collectionContract, JsonProperty
> containerProperty)\r\n at
> Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter
> writer, Object value, JsonContract valueContract, JsonProperty member,
> JsonContainerContract containerContract, JsonProperty
> containerProperty)\r\n at
> Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter
> jsonWriter, Object value, Type objectType)\r\n at
> Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter
> jsonWriter, Object value, Type objectType)\r\n at
> Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object
> value)\r\n at
> System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type
> type, Object value, Stream writeStream, Encoding
> effectiveEncoding)\r\n at
> System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type
> type, Object value, Stream writeStream, Encoding
> effectiveEncoding)\r\n at
> System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type
> type, Object value, Stream writeStream, HttpContent content)\r\n at
> System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type
> type, Object value, Stream writeStream, HttpContent content,
> TransportContext transportContext, CancellationToken
> cancellationToken)\r\n--- End of stack trace from previous location
> where exception was thrown ---\r\n at
> System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
> task)\r\n at
> System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
> task)\r\n at
> System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at
> System.Web.Http.WebHost.HttpControllerHandler.d__1b.MoveNext()","innerException":{"message":"An
> error has occurred.","exceptionMessage":"Exception has been thrown by
> the target of an
> invocation.","exceptionType":"System.Reflection.TargetInvocationException","stackTrace":"
> at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[]
> arguments, Signature sig, Boolean constructor)\r\n at
> System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags
> invokeAttr, Binder binder, Object[] parameters, CultureInfo
> culture)\r\n at System.RuntimeType.CreateInstanceImpl(BindingFlags
> bindingAttr, Binder binder, Object[] args, CultureInfo culture,
> Object[] activationAttributes, StackCrawlMark& stackMark)\r\n at
> System.Activator.CreateInstance(Type type, BindingFlags bindingAttr,
> Binder binder, Object[] args, CultureInfo culture, Object[]
> activationAttributes)\r\n at System.Activator.CreateInstance(Type
> type, Object[] args)\r\n at
> System.Data.Entity.Core.Common.Internal.Materialization.CoordinatorScratchpad.Compile()\r\n
> at
> System.Data.Entity.Core.Common.Internal.Materialization.CoordinatorScratchpad.Compile()\r\n
> at
> System.Data.Entity.Core.Common.Internal.Materialization.CoordinatorScratchpad.Compile()\r\n
> at
> System.Data.Entity.Core.Common.Internal.Materialization.Translator.TranslateColumnMap[T](ColumnMap
> columnMap, MetadataWorkspace workspace, SpanIndex spanIndex,
> MergeOption mergeOption, Boolean streaming, Boolean
> valueLayer)","innerException":{"message":"An error has
> occurred.","exceptionMessage":"Instances of abstract classes cannot be
> created.","exceptionType":"System.InvalidOperationException","stackTrace":"
> at
> System.Runtime.CompilerServices.RuntimeHelpers._CompileMethod(IRuntimeMethodInfo
> method)\r\n at
> System.Reflection.Emit.DynamicMethod.CreateDelegate(Type delegateType,
> Object target)\r\n at
> System.Linq.Expressions.Compiler.LambdaCompiler.CreateDelegate()\r\n
> at
> System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression
> lambda, DebugInfoGenerator debugInfoGenerator)\r\n at
> System.Linq.Expressions.Expression`1.Compile()\r\n at
> System.Data.Entity.Core.Common.Internal.Materialization.CoordinatorFactory`1..ctor(Int32
> depth, Int32 stateSlot, Expression`1 hasData, Expression`1 setKeys,
> Expression`1 checkKeys, CoordinatorFactory[] nestedCoordinators,
> Expression`1 element, Expression`1 wrappedElement, Expression`1
> elementWithErrorHandling, Expression`1 initializeCollection,
> RecordStateFactory[] recordStateFactories)\r\n at
> System.Data.Entity.Core.Common.Internal.Materialization.CoordinatorFactory`1..ctor(Int32
> depth, Int32 stateSlot, Expression hasData, Expression setKeys,
> Expression checkKeys, CoordinatorFactory[] nestedCoordinators,
> Expression element, Expression elementWithErrorHandling, Expression
> initializeCollection, RecordStateFactory[] recordStateFactories)"}}}}

推荐答案

2个问题

  1. 错误消息明确指出您无法映射抽象类
  2. 您正在使用可查询扩展Project().To<T>(),在这种情况下,它似乎受到linq提供程序的限制,如
  1. The error message clearly states that you can't map an abstract class
  2. You're working with Queryable extensions Project().To<T>() which seems to suffer, in this case, from limitations due to linq provider, as mentionned here

=>使您的基类具体化

=> make your base class concrete

=>从IEnumerable<T>而不是IQueryable<T>映射,而不使用Queryable扩展名.

=> map from an IEnumerable<T> instead of an IQueryable<T>, without using Queryable extensions.

这篇关于EF6自动映射器继承/抽象类错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆