WCF /实体框架 - 如何获得一个不错的DataContract?

时间:2011-09-13 17:22:42

标签: wcf entity-framework

是否有一种干净的方法可以将自动生成的EF类与WCF一起使用,而不必为WCF DataContracts手工制作类? 这些类位于LAIT.Entities.dll

ProductService.vb

  

公共类ProductService       实现IProductService

Public Function GetWorkOrder(ByVal WorkOrderID As Integer) As
     

WorkOrder实现IProductService.GetWorkOrder

    Using dc As New LAIT.Model.LAITEntities
        Try
            Dim _Order = (From o In dc.WorkOrder
                           Where o.WorkOrderID = WorkOrderID
                          Select o).SingleOrDefault

            Return _Order
        Catch ex As Exception
            Return Nothing
        End Try
    End Using

End Function 
     

结束班

IProductService.vb

  

公共接口IProductService

<OperationContract()>
Function GetWorkOrder(ByVal WorkOrderID As Integer) As
     

LAIT.Entities.WorkOrder

     

结束界面

2 个答案:

答案 0 :(得分:2)

是。为此,您需要编辑VS用于自动生成实体的T4文件。您所需要做的就是确保所有课程都使用<DataContract>属性进行修饰,并且您的属性标有<DataMember>属性。我假设您正在使用POCO实体,因为实体对象和STE都已标记为DataContract,您无需执行任何操作即可在WCF服务中使用它们。

话虽如此,我强烈建议您不要在WCF上使用实体对象。你应该在这个场景中使用STE或POCO。

答案 1 :(得分:0)

Windows Communication Foundation(WCF)无法直接序列化或反序列化POCO代理类型,因为DataContractSerializer序列化引擎只能序列化和反序列化已知类型。代理类型不是已知类型。

如果您的POCO实体没有任何“导航属性”,您可以通过在班级中添加<DataContract> and <DataMember>属性,通过WCF服务对您的实体进行序列化对象。

但是对于具有“导航属性”的实体除了在类中添加<DataContract> and <DataMember>属性之外,还需要在WCF服务中进行一些更改,如下所示。在WCF服务项目中添加以下calss。

1

Imports System.Data.Objects
Imports System.ServiceModel.Description
Imports System.ServiceModel.Channels

Public Class ApplyDataContractResolverAttribute
    Inherits Attribute
    Implements IOperationBehavior

    Public Sub New()
    End Sub

    Public Sub AddBindingParameters(ByVal operationDescription As OperationDescription, ByVal parameters As BindingParameterCollection) Implements IOperationBehavior.AddBindingParameters
    End Sub

    Public Sub ApplyClientBehavior(ByVal operationDescription As OperationDescription, ByVal proxy As System.ServiceModel.Dispatcher.ClientOperation) Implements IOperationBehavior.ApplyClientBehavior
        Dim dataContractSerializerOperationBehavior As DataContractSerializerOperationBehavior = operationDescription.Behaviors.Find(Of DataContractSerializerOperationBehavior)()
        dataContractSerializerOperationBehavior.DataContractResolver = New ProxyDataContractResolver()
    End Sub

    Public Sub ApplyDispatchBehavior(ByVal operationDescription As OperationDescription, ByVal dispatch As System.ServiceModel.Dispatcher.DispatchOperation) Implements IOperationBehavior.ApplyDispatchBehavior
        Dim dataContractSerializerOperationBehavior As DataContractSerializerOperationBehavior = operationDescription.Behaviors.Find(Of DataContractSerializerOperationBehavior)()
        dataContractSerializerOperationBehavior.DataContractResolver = New ProxyDataContractResolver()
    End Sub

    Public Sub Validate(ByVal operationDescription As OperationDescription) Implements IOperationBehavior.Validate
        ' Do validation.
    End Sub
End Class

2.打开服务接口文件。默认情况下,它被称为IService1。

3.使用以下代码替换定义服务接口文件的代码:

C#
[ServiceContract]
public interface IService1
{
    [OperationContract]
    [ApplyDataContractResolver]
    void UpdateOrder(Order updated);

    [OperationContract]
    [ApplyDataContractResolver]
    Order GetOrder(int OrderID);
}

VB
<ServiceContract> _
Public Interface IService1
    <OperationContract> _
    <ApplyDataContractResolver> _
    Sub UpdateOrder(updated As Order)

    <OperationContract> _
    <ApplyDataContractResolver> _
    Function GetOrder(OrderID As Integer) As Order
End Interface

你准备好了。