2016-07-14 42 views
0

我正在使用Entity Framework 6并将我的查询结果从WCF服务中发出。如果我尝试发送查询返回的实体,则由于动态代理服务器而出现异常。将对象映射到同一类型的另一个对象是否有意义?

我给这家以前的解决方法是使用这样的代码......

return PatientServiceLogic.GetAll() 
    .Select(p => new Patient { 
    ID = p.ID, 
    FirstName = p.FirstName, 
    Surname = p.Surname, 
    AccidentDate = p.AccidentDate 
    }) 
    .ToList(); 

这是一个简单的例子。正如你可以想象的那样,当对象图形增长时,这可能会非常痛苦。

我刚刚发现AutoMapper,看起来它会为我节省很多样板代码。当我想发送一组Patient对象,这些对象将在客户端应用程序的网格中使用时,我不想要完整的Patient对象图,我想要一个简化的扁平版本。为此,PatientDto类将会很好。

但是,假设我想要发出完整的对象图。我没有看到创建Patient类的碳拷贝以及所有相关类,然后将一个拷贝到另一个类,只是为了能够将它们发送出去。重用EF生成的类会更有意义,并将Patient对象映射到新的Patient对象,该对象(在代码中创建,不是EF)没有动态代理。这基本上是我的代码在做什么。

我试过这个,但是我得到了无用的和非描述性的异常,显示在下面。

任何人有任何意见?这是一个明智的事情吗?如果不是,处理这种情况的最佳方法是什么?

这是我从WCF测试客户端了,当我试图调用使用映射设置服务与MapperConfiguration(c => c.CreateMap<Patient, Patient>())

在接收到http://localhost:5448/PatientsService.svc HTTP响应时发生错误例外。这可能是由于服务端点绑定不使用HTTP协议。这也可能是由于HTTP请求上下文被服务器中止(可能是由于服务关闭)。查看服务器日志获取更多详细信

服务器堆栈跟踪:

在 System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(引发WebException 引发WebException,HttpWebRequest的请求,HttpAbortReason abortReason)
在 System.ServiceModel.Channels.HttpChannelFactory`1。 HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan 超时)在 System.ServiceModel.Channels.RequestChannel.Request(消息消息, TimeSpan超时)在 System.ServiceM odel.Dispatcher.RequestChannelBinder.Request(消息 消息,TimeSpan超时) System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway,ProxyOperationRuntime operation,Object [] ins, Object [] outs,TimeSpan timeout ) System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime operation)at System.ServiceModel.Channels.ServiceChannelProxy。调用(即时聊天 消息)[0]时

异常重新抛出:在 在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(即时聊天 reqMsg,即时聊天retMsg)System.Runtime.Remoting.Proxies.RealProxy。 PrivateInvoke(MessageData & MSGDATA,的Int32类型)在PatientsService.GetPatients()在 PatientsServiceClient.GetPatients()

内部异常:

底层连接已关闭:接收到 时发生意外错误。在System.Net.HttpWebRequest.GetResponse()在 System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(时间跨度 超时)

内部异常:

无法读取来自传输连接的数据:现有的 连接被远程主机强制关闭。 at System.Net.Sockets.NetworkStream.Read(Byte [] buffer,Int32 offset, Int32 size)at System.Net.PooledStream.Read(Byte [] buffer,Int32 offset,Int32 size)at System.Net .Connection.SyncRead(HttpWebRequest的请求,布尔 userRetrievedStream,布尔probeRead)

内部异常:

一个现有的连接由远程主机在 System.Net.Sockets.Socket强制关闭。接收(字节[]缓冲区,Int32偏移量,Int32 siz E,的SocketFlags的SocketFlags)在 System.Net.Sockets.NetworkStream.Read(字节[]缓冲区,偏移的Int32, 的Int32大小)

+0

问题_“为什么我们使用数据传输对象而不是我们的实体类跨越层”_已被讨论为死亡。你的研究显示了什么?你是否想要回答这个问题?还是你想解决这个问题? – CodeCaster

+0

@CodeCaster其实,我没有这样想过。当EF创建它们时,我正在考虑将EF生成的类作为POCO(如果您查看代码,它们似乎是),并在顶部添加代理。我假设(也许不正确),当你自己创建它们时(如'var p = new Patient()'),那么你得到没有代理的POCO。从这个角度来看,创建相同的DTO似乎毫无意义。请你可以澄清这一点,因为我不知道我错在哪里。 –

+0

@CodeCaster有何评论?我应该如何做到这一点?任何人都可以评论? –

回答

1

您当前的问题似乎是你的数据库连接被关闭,你finisheds工作之前与你的数据。

尝试使用

db.mainEntity.Include(i=>i.relatedtable).Include(i=>i.anotherRelatedtable) 

在查询所有相关实体。

一个很好的理由不要让你的对象的序列化1对1复制的循环(你可能已经使用JSON-feeded组件时之前解决它们):

父亲有孩子,和孩子有父亲,有孩子,有......溢出!

+0

感谢您的回复,但它有什么用?所有相关的实体已经加载,所以我不确定使用.Include()将要添加的内容。我的根本问题(这不是我在这个问题中解决的问题)是关联的实体在连接关闭之前不会被加载。为了避免这种情况,我需要能够告诉查询哪些关联实体**不包括**。请你澄清。 –

+0

如果启用加载启用。实体只会在引用时加载相关元素。我还没有尝试过,但是,如果您的对象在内存中,我不确定EF会在尝试访问它们之前分配子元素。使用“包含”应该强制在进行查询时更新这些关系。当然,**必须在连接关闭前询问结果**,因此在退出上下文的使用语句或范围之前,请在结果集上尝试使用ToList() –

相关问题