EF6自动映射器继承/抽象类错误 [英] EF6 Automapper Inheritance/Abstract Class Errors
问题描述
我正在使用带有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个问题
- The error message clearly states that you can't map an abstract class
- 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屋!