带有 EF 的 ADO.NET 数据服务实现每个具体类型表 (TPCT) 继承
我正在使用一个在多个表中具有重复数据的 SQL 数据源。我无法控制数据库。对于我的项目,我创建了一个 EF 模型和一个公开它的 ADO.NET 数据服务(使用 VS 2008)。我还有一个使用该服务的 .NET 客户端应用程序。
现在,这些数据库表有大量公共字段,我需要在向服务发送插入请求之前在客户端中对这些字段进行水化。因此,为了避免重复代码,我在 EF 模型中创建了一个抽象基类,并将所有公共属性放入其中。该基类的实体集名称是OrderEntries
。从它继承的实体之一称为OEORDH
。它映射到数据库表。为了公开此实体,我创建了一个 WebGet 服务方法,因为查询使用 OfType
方法,该方法不支持到 ATOM 的转换;因此我不能在我的客户端中使用它。方法如下:
<WebGet()> _
Public Function Orders() As IQueryable(Of OEORDH)
Dim results = From x In Me.CurrentDataSource.OrderEntries.OfType(Of OEORDH)()
Return results
End Function
当我在浏览器中访问此方法时(http://localhost:1187/MyService.svc/Orders),我收到一个非常通用的错误:
<link rel="self" title="Orders" href="Orders" />
<m:error>
<m:code></m:code>
<m:message xml:lang="en-US">An error occurred while processing this request.</m:message>
</m:error>
但我知道查询被调用,而且,当我在调试中观察“本地”窗口,我发现它返回了正确的对象集合。其他查询非继承实体的 Web 方法也可以正常工作。怎么了?
更新 我听从了 Steve 的建议,将 IncludeExceptionDetailInFaults
设置为 true。我还将 UseVerboseErrors
设置为 true。跟踪日志现在显示抛出的异常是 System.ServiceModel.CommunicationObjectAbortedException,它仍然非常通用。我在网上搜索过,但没有找到任何具体的信息。该消息是: 通信对象 System.ServiceModel.Channels.TransportReplyChannelAcceptor+TransportReplyChannel 无法用于通信,因为它已被中止。这是堆栈内容:
System.ServiceModel.Channels.CommunicationObject.ThrowIfAborted()
System.ServiceModel.Channels.InputQueueChannel`1.EndDequeue(IAsyncResult result, TDisposable& item)
System.ServiceModel.Channels.ReplyChannel.EndTryReceiveRequest(IAsyncResult result, RequestContext& context)
System.ServiceModel.Dispatcher.ReplyChannelBinder.EndTryReceive(IAsyncResult result, RequestContext& requestContext)
System.ServiceModel.Dispatcher.ErrorHandlingReceiver.EndTryReceive(IAsyncResult result, RequestContext& requestContext)
System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
System.ServiceModel.Channels.InputQueue`1.AsyncQueueReader.Set(Item item)
System.ServiceModel.Channels.InputQueue`1.Shutdown(CommunicationObject communicationObject)
System.ServiceModel.Channels.InputQueueChannel`1.OnClosing()
System.ServiceModel.Channels.CommunicationObject.Abort()
System.ServiceModel.Dispatcher.ReplyChannelBinder.Abort()
System.ServiceModel.Channels.ServiceChannel.OnAbort()
System.ServiceModel.Channels.CommunicationObject.Abort()
System.Data.Services.DelegateBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
System.ServiceModel.Channels.BodyWriter.WriteBodyContents(XmlDictionaryWriter writer)
System.ServiceModel.Channels.BodyWriterMessage.OnWriteBodyContents(XmlDictionaryWriter writer)
System.ServiceModel.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer)
System.ServiceModel.Channels.Message.WriteMessage(XmlDictionaryWriter writer)
System.ServiceModel.Channels.HttpStreamMessageEncoderFactory.HttpStreamMessageEncoder.WriteMessage(Message message, Stream stream)
System.ServiceModel.Channels.HttpStreamMessageEncoderFactory.HttpStreamMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
System.ServiceModel.Channels.WebMessageEncoderFactory.WebMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message)
System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)
System.ServiceModel.Channels.HttpRequestContext.OnReply(Message message, TimeSpan timeout)
System.ServiceModel.Activation.HostedHttpContext.OnReply(Message message, TimeSpan timeout)
System.ServiceModel.Channels.RequestContextBase.Reply(Message message, TimeSpan timeout)
System.ServiceModel.Channels.RequestContextBase.Reply(Message message)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Reply(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessageCleanup(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Dispatch(MessageRpc& rpc, Boolean isOperationContextSet)
System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
System.ServiceModel.Channels.InputQueue`1.AsyncQueueReader.Set(Item item)
System.ServiceModel.Channels.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.InputQueue`1.EnqueueAndDispatch(T item, ItemDequeuedCallback dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.InputQueueChannel`1.EnqueueAndDispatch(TDisposable item, ItemDequeuedCallback dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, ItemDequeuedCallback dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, ItemDequeuedCallback callback)
System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
System.ServiceModel.PartialTrustHelpers.PartialTrustInvoke(ContextCallback callback, Object state)
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequestWithFlow(Object state)
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2()
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke()
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks()
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(Object state)
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
I am working with a SQL data source that has duplicate data in multiple tables. I have no control over the database. For my project, I've created an EF model and an ADO.NET data service (using VS 2008) that exposes it. I also have a .NET client application that consumes the service.
Now, these db tables have a large number of fields common, which I need to hydrate in my client before sending an insert request to the service. So, wanting to avoid repetitive code, I created an abstract base class in my EF model and put all the common properties in it. The entity set name of this base class is OrderEntries
. One of the entities inheriting from it is called OEORDH
. It maps to a db table. To expose this entity, I created a WebGet service method because the query uses OfType
method, which has no supported translation to ATOM; hence I can't use it in my client. Here's the method:
<WebGet()> _
Public Function Orders() As IQueryable(Of OEORDH)
Dim results = From x In Me.CurrentDataSource.OrderEntries.OfType(Of OEORDH)()
Return results
End Function
When I access this method in the browser (http://localhost:1187/MyService.svc/Orders), I get a very generic error back:
<link rel="self" title="Orders" href="Orders" />
<m:error>
<m:code></m:code>
<m:message xml:lang="en-US">An error occurred while processing this request.</m:message>
</m:error>
But I know that the query gets called, and moreover, when I watch the Locals window in debug, I see that it returns the right collection of objects. Other web methods that query non-inheriting entities work just fine. What is wrong?
UPDATE
I followed Steve's advice and set IncludeExceptionDetailInFaults
to true. I also set UseVerboseErrors
to true. The trace log now shows that the exception being thrown is System.ServiceModel.CommunicationObjectAbortedException, which is still pretty generic. I searched the web, but didn't find anything concrete. The message is: The communication object, System.ServiceModel.Channels.TransportReplyChannelAcceptor+TransportReplyChannel, cannot be used for communication because it has been Aborted. Here's the stack content:
System.ServiceModel.Channels.CommunicationObject.ThrowIfAborted()
System.ServiceModel.Channels.InputQueueChannel`1.EndDequeue(IAsyncResult result, TDisposable& item)
System.ServiceModel.Channels.ReplyChannel.EndTryReceiveRequest(IAsyncResult result, RequestContext& context)
System.ServiceModel.Dispatcher.ReplyChannelBinder.EndTryReceive(IAsyncResult result, RequestContext& requestContext)
System.ServiceModel.Dispatcher.ErrorHandlingReceiver.EndTryReceive(IAsyncResult result, RequestContext& requestContext)
System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
System.ServiceModel.Channels.InputQueue`1.AsyncQueueReader.Set(Item item)
System.ServiceModel.Channels.InputQueue`1.Shutdown(CommunicationObject communicationObject)
System.ServiceModel.Channels.InputQueueChannel`1.OnClosing()
System.ServiceModel.Channels.CommunicationObject.Abort()
System.ServiceModel.Dispatcher.ReplyChannelBinder.Abort()
System.ServiceModel.Channels.ServiceChannel.OnAbort()
System.ServiceModel.Channels.CommunicationObject.Abort()
System.Data.Services.DelegateBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
System.ServiceModel.Channels.BodyWriter.WriteBodyContents(XmlDictionaryWriter writer)
System.ServiceModel.Channels.BodyWriterMessage.OnWriteBodyContents(XmlDictionaryWriter writer)
System.ServiceModel.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer)
System.ServiceModel.Channels.Message.WriteMessage(XmlDictionaryWriter writer)
System.ServiceModel.Channels.HttpStreamMessageEncoderFactory.HttpStreamMessageEncoder.WriteMessage(Message message, Stream stream)
System.ServiceModel.Channels.HttpStreamMessageEncoderFactory.HttpStreamMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
System.ServiceModel.Channels.WebMessageEncoderFactory.WebMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message)
System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)
System.ServiceModel.Channels.HttpRequestContext.OnReply(Message message, TimeSpan timeout)
System.ServiceModel.Activation.HostedHttpContext.OnReply(Message message, TimeSpan timeout)
System.ServiceModel.Channels.RequestContextBase.Reply(Message message, TimeSpan timeout)
System.ServiceModel.Channels.RequestContextBase.Reply(Message message)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Reply(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessageCleanup(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.Dispatch(MessageRpc& rpc, Boolean isOperationContextSet)
System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
System.ServiceModel.Channels.InputQueue`1.AsyncQueueReader.Set(Item item)
System.ServiceModel.Channels.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.InputQueue`1.EnqueueAndDispatch(T item, ItemDequeuedCallback dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.InputQueueChannel`1.EnqueueAndDispatch(TDisposable item, ItemDequeuedCallback dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, ItemDequeuedCallback dequeuedCallback, Boolean canDispatchOnThisThread)
System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, ItemDequeuedCallback callback)
System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
System.ServiceModel.PartialTrustHelpers.PartialTrustInvoke(ContextCallback callback, Object state)
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequestWithFlow(Object state)
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke2()
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.WorkItem.Invoke()
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ProcessCallbacks()
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.CompletionCallback(Object state)
System.ServiceModel.Channels.IOThreadScheduler.CriticalHelper.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
System.ServiceModel.Diagnostics.Utility.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论