不支持具有“Domain.Entities.Request"类型输入和“Domain.Entities.Base"类型检查的“TypeIs"表达式 [英] The 'TypeIs' expression with an input of type 'Domain.Entities.Request' and a check of type 'Domain.Entities.Base' is not supported

查看:15
本文介绍了不支持具有“Domain.Entities.Request"类型输入和“Domain.Entities.Base"类型检查的“TypeIs"表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到此错误:

不支持具有Domain.Flood.Entities.Things.SomeObject"类型输入和Domain.Entities.Base"类型检查的TypeIs"表达式.LINQ to Entities 查询仅支持实体类型和复杂类型.

The 'TypeIs' expression with an input of type 'Domain.Flood.Entities.Things.SomeObject' and a check of type 'Domain.Entities.Base' is not supported. Only entity types and complex types are supported in LINQ to Entities queries.

我正在尝试调用我的 OData API 并在我的对象上展开 CreatedBy 属性.CreatedBy 属性在基类中,是一种用户类型.所以我的基类看起来像这样:

I'm trying to call my OData API and Expand the CreatedBy property on my object. The CreatedBy Property is in the base class and is a type of User. So my Base Class looks like this:

[DataContract(Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
    public abstract class Base
    {    
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [DataMember]
        public int Id { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public string Description { get; set; }    

        private User createdBy;    
        [DataMember]
        public virtual User CreatedBy
        {
            get
            {
                return createdBy;
            }
            set
            {
                createdBy = value;
            }
        } 
    }

当我尝试获取从基类继承的小部件时,并且我还想包含名为 CreatedBy 的用户对象时,出现此错误.如果我不展开 CreatedBy 对象,我就不会收到错误消息.这是奇怪的部分,我有另一个 User 属性不在基类上,而是在我的 SomeObject 类中,称为 AssignedTo.如果我对此进行扩展,一切都是桃色.所以在基类上展开 User 对象,没有 bueno.将 User 对象向上展开几个级别,bueno.

When I try to get my widget that inherits from the base class, and I want to also include the User object called CreatedBy, I get this error. If I don't expand the CreatedBy object I don't get the error. Here's the weird part, I have another User property not on the base class but up in my SomeObject class called AssignedTo. If I expand on that, everything is peachy. So Expand the User object on the base class, no bueno. Expand the User object up a few levels, bueno.

     {
         Container.SendingRequest += new EventHandler<SendingRequestEventArgs>(OnSendingRequest);
         ViewBag.Data = Container.SomeObject.Expand("Address, CreatedBy").ToList();
         return View();
     }

这是堆栈跟踪:

Exception Details: System.Data.Services.Client.DataServiceClientException: <?xml version="1.0" encoding="utf-8"?>
<m:error xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
 <m:code />
 <m:message xml:lang="en-US">An error has occurred.</m:message>
 <m:innererror>
   <m:message>The 'ObjectContent`1' type failed to serialize the response body for content type 'application/atom+xml; charset=utf-8'.</m:message>
   <m:type>System.InvalidOperationException</m:type>
   <m:stacktrace></m:stacktrace>
   <m:internalexception>
     <m:message>The 'TypeIs' expression with an input of type 'Domain.Flood.Entities.Things.SomeObject' and a check of type 'Domain.Entities.Base' is not supported. Only entity types and complex types are supported in LINQ to Entities queries.</m:message>
     <m:type>System.NotSupportedException</m:type>
     <m:stacktrace>   at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.GetIsOrAsTargetType(ExpressionType operationType, Type toClrType, Type fromClrType)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.IsTranslator.TypedTranslate(ExpressionConverter parent, TypeBinaryExpression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.ConditionalTranslator.TypedTranslate(ExpressionConverter parent, ConditionalExpression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MemberInitTranslator.TypedTranslate(ExpressionConverter parent, MemberInitExpression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MemberInitTranslator.TypedTranslate(ExpressionConverter parent, MemberInitExpression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MemberInitTranslator.TypedTranslate(ExpressionConverter parent, MemberInitExpression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding&amp; binding)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression&amp; source, DbExpressionBinding&amp; sourceBinding, DbExpression&amp; lambda)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert()&#xD;
  at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)&#xD;
  at System.Data.Entity.Core.Objects.ObjectQuery`1.&lt;&gt;c__DisplayClassb.&lt;GetResults&gt;b__a()&#xD;
  at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)&#xD;
  at System.Data.Entity.Core.Objects.ObjectQuery`1.&lt;&gt;c__DisplayClassb.&lt;GetResults&gt;b__9()&#xD;
  at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)&#xD;
  at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)&#xD;
  at System.Data.Entity.Core.Objects.ObjectQuery`1.&lt;System.Collections.Generic.IEnumerable&lt;T&gt;.GetEnumerator&gt;b__0()&#xD;
  at System.Lazy`1.CreateValue()&#xD;
  at System.Lazy`1.LazyInitValue()&#xD;
  at System.Lazy`1.get_Value()&#xD;
  at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()&#xD;
  at System.Web.Http.OData.Formatter.Serialization.ODataFeedSerializer.WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer, ODataSerializerContext writeContext)&#xD;
  at System.Web.Http.OData.Formatter.Serialization.ODataFeedSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)&#xD;
  at System.Web.Http.OData.Formatter.Serialization.ODataFeedSerializer.WriteObject(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)&#xD;
  at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)&#xD;
  at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext)&#xD;
--- End of stack trace from previous location where exception was thrown ---&#xD;
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)&#xD;
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)&#xD;
  at System.Runtime.CompilerServices.TaskAwaiter.GetResult()&#xD;
  at System.Web.Http.WebHost.HttpControllerHandler.&lt;WriteBufferedResponseContentAsync&gt;d__14.MoveNext()</m:stacktrace>
   </m:internalexception>
 </m:innererror>
</m:error>

阅读错误消息,我可以看到 Linq to Entities 正在尝试将一件事转换为另一件事,但到目前为止,我真的不知道这是什么.

Reading the error message, I can see that Linq to Entities is trying to convert one thing to another, but that's so far under the hood that I really don't know.

我注意到的另一件事是我的 OData 元数据显示了所有内容,而不仅仅是具有数据契约的内容.它过去只包含具有数据契约的类.这很奇怪吧?我查看了我的源代码管理以查看最近几个变更集中的更改,但我没有看到与我的 Base 类、Users 类或 SomeObject 类有关的任何内容.也与我的 API 无关.

One other thing that I noticed is that my OData metadata is showing everything, not just the stuff that has data contracts. It used to only include classes with data contracts. That's weird right? I went through my source control to see what changed in the last few changesets and I don't see anything having to do with my Base class, Users class or my SomeObject Class. Nothing having to do with my API either.

如果我能说得更清楚,请告诉我.我觉得我好像遗漏了什么.

If I can be more clear, please let me know. I feel like I'm leaving something out.

推荐答案

如果你仔细阅读错误:

输入类型为TypeIs"的表达式'Domain.Flood.Entities.Things.SomeObject' 和类型检查不支持Domain.Entities.Base".

The 'TypeIs' expression with an input of type 'Domain.Flood.Entities.Things.SomeObject' and a check of type 'Domain.Entities.Base' is not supported.

这意味着 OData 尝试一个查询,使 EF 生成一个带有TypeIs"函数的查询,这本身就很好,但是 TypeIs 的两个操作数都必须是实体类型或复杂类型:

This means that OData tries a query that makes EF generate one with a "TypeIs" function which is fine in itself, but both operands of TypeIs have to be either an Entity Type or a Complex type:

LINQ to Entities 仅支持实体类型复杂类型查询.

Only entity types and complex types are supported in LINQ to Entities queries.

也就是说,在 EF DbContext 中,使用 ModelBuilder,您必须确保 SomeObject 和 Base 都是上下文已知的实体类型或复杂类型.这是使用 Fluent API 来完成的:

That is, in the EF DbContext, using the ModelBuilder, you have to make sure both SomeObject and Base are known to the context either as Entity types or Complex types. Here's to do it with Fluent API:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Base>(); //EF should crawl and configure all derived types as well.
}

另外,在使用 DbModelBuilder.Ignore() 时要特别注意不要忽略任何重要的类型.

Also, pay special attention when using DbModelBuilder.Ignore() not to ignore any important type.

更新:

您还可以使用 ODataConventionModelBuilder 告诉 OData 将所有超类继承的属性视为继承类型的属性:

You can also tell OData to treat all super class inherited properties as the inherited type's own with ODataConventionModelBuilder :

使用 System.Web.OData:

modelBuilder.EntityType<SomeObject>().DerivesFromNothing();

使用System.Web.Http.OData:

modelBuilder.Entity<SomeObject>().DerivesFromNothing();

这篇关于不支持具有“Domain.Entities.Request"类型输入和“Domain.Entities.Base"类型检查的“TypeIs"表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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