WCF/Entity Framework - How To Get a Nice DataContract?
Is 开发者_运维百科there a clean way of using the auto-generated EF classes with WCF instead of having to hand-make classes for WCF DataContracts? The classes are located in the LAIT.Entities.dll
ProductService.vb
Public Class ProductService Implements IProductService
Public Function GetWorkOrder(ByVal WorkOrderID As Integer) As
WorkOrder Implements 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
End Class
IProductService.vb
Public Interface IProductService
<OperationContract()> Function GetWorkOrder(ByVal WorkOrderID As Integer) As
LAIT.Entities.WorkOrder
End Interface
Yes. For that you need to edit the T4 file that VS uses to auto generate your entities. All you need to do is to make sure that all your classes are decorated with <DataContract>
attribute and your properties are marked with <DataMember>
attribute. I assume that you are using POCO entities because both Entity Objects and STEs are already marked as DataContract and you don't need to do anything in order to use them in your WCF services.
Having said that, I strongly discourage you from using Entity Objects across the wire with WCF. You should use either STEs or POCOs in this scenaio.
The POCO proxy type cannot be directly serialized or deserialized by the Windows Communication Foundation (WCF), because the DataContractSerializer serialization engine can only serialize and deserialize known types. The proxy type is not a known type.
If your POCO entities don't have any "Navigation Properties" you can have serialized objects of your entities through WCF Services by adding <DataContract> and <DataMember>
properties in your class.
But for Entities with "Navigation Properties" In addition of adding <DataContract> and <DataMember>
properties in your class you need to have some changes in your WCF Service as follows. Add the following calss in your WCF Service project.
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.Open the service interface file. By default, it is called IService1.
3.Replace the code that defines the service interface file with the following code:
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
And you are ready to go.
精彩评论