如何使用linq to sql序列化wcf中的对象列表

时间:2012-06-27 06:23:22

标签: wcf-data-services wcf-binding

我在visual studio express 2010中构建了wcf web服务。我使用Linq to Sql来操作数据库。我在哪里有表EmpMaster(主键表)和EmpDetail(F键表)与EmpID的关系。 我到目前为止在本地部署了此Web服务。并尝试在我的Web应用程序中使用Linq to sql Query访问Employee主数据以及详细数据。我的Web应用程序是基于MVC的应用程序。而我可以通过网络服务在网络应用中访问员工主数据。但默认情况下应加载员工详细信息条目。默认情况下, DeferredLoadingEnabled 已启用。我可以在调试Web服务时看到Web服务中的记录集。但在访问Web应用程序中的详细列表数据时,我收到错误。如

"the underlying connection was closed the connection was closed unexpectedly "

我在客户端网络配置中添加了:

<binding name="BasicHttpBinding_IEmployeeManagerService"  openTimeout="10:10:00" receiveTimeout="10:10:00" sendTimeout="10:10:00"
      allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
      maxBufferSize="104857600" maxBufferPoolSize="104857600" maxReceivedMessageSize="104857600"
      messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
      useDefaultWebProxy="true">
       <readerQuotas maxDepth="104857600" maxStringContentLength="104857600"
                     maxArrayLength="104857600" maxBytesPerRead="104857600" maxNameTableCharCount="104857600" />

       </binding>

应该是什么问题?

   **`**Edited:**`** 

Public Function GetEmployeeDetail(ByVal id As String) As EmployeeDetail Implements IEmployeeManagerService.GetEmployeeDetail
    Dim _empDetail As New EmployeeDetail()
    If Not id Is Nothing Then
        _empDetail = _dbContext.EmployeeDetails.Where(Function(e) e.EmpId = id ).FirstOrDefault()
    End If
    Return _empDetail
End Function

2 个答案:

答案 0 :(得分:1)

嗯,在您的情况下,延迟加载(或延迟加载)意味着仅在您“调用”它们时才会检索EmpDetail数据。

因此,您检索EmpMaster数据,并且当您使用属性master.EmpDetail.Name时,将向数据库发送一个新请求以获取与主的EmpDetail对应的EmpDetail。

当然,数据库必须可用(上下文仍然存在)。

您可以在调试时看到EmpDetail数据:当您尝试在Debug中查看实体的导航属性时,它还会查询数据库以获取值。

为了避免这些问题,你可以“手动”加载你知道需要的数据(顺便说一下,如果你知道以后需要所有这些数据,你将避免多次调用数据库)。

为此,您可以使用

Include()扩展名。

context.EmpMaster.Include("EmpDetail").Where...

或选择对象中需要的值(匿名或非匿名)

your query.Select(m => new {
   m.Name,
   m.EmpDetail.Propertyx,
 ...
 });

编辑

右。我已经习惯了Linq到实体和c#,你使用Linq to SQL和vb.net。

因此无法使用Include(),但可能LoadWith()

如果你的“EmployeeDetail”课程中有“状态”属性,你可以试试这样的。

Public Function GetEmployeeDetail(ByVal id As String) As EmployeeDetail Implements IEmployeeManagerService.GetEmployeeDetail
    Dim _empDetail As New EmployeeDetail()
    If Not id Is Nothing Then
         Dim dlo As DataLoadOptions = New DataLoadOptions()
         dlo.LoadWith(Of EmployeeDetails)(Function(e As EmployeeDetails) e.Status)
         _dbContext.LoadOptions = dlo
        _empDetail = _dbContext.EmployeeDetails.Where(Function(e) e.EmpId = id ).FirstOrDefault()
    End If
    Return _empDetail
End Function

如果您没有“状态”属性,则应进行内部联接。 EmpMaster和EmployeeDetail的相同想法

答案 1 :(得分:0)

wel..wel..wel ....发现诀窍但冷却没有得到答案。我删除了EmpMaster和EmpDetail之间的映射,然后重新生成.dbml。至少在这个时候,每件事都做得很完美。但是当我在普通的asp.net web服务中尝试时,我收到了EmpMaster对象的序列化错误。和错误是说循环参考... bla bla bla ..不知道为什么。当我在Database Context类中检查时,似乎没有任何东西。然后我尝试通过删除sql server中两个表之间的映射。听起来对我有用。 ......第二种方式是here