在WCF中使用时,“包括”与实体版本6语法复杂的对象将不会返回 [英] Complex Object won't return when using 'include' syntax in WCF with Entity Version 6
问题描述
好了,这其中有难住我了,因为我刚刚看到我的客户基本上断开,并传回包括对象时终止。但是它工作正常不跨越一个WCF服务。但问题是,我真的想通过导航设置这些连接的对象。
Okay so this one has got me stumped as I just see that my client basically disconnects and terminates when returning an object with 'include'. However it works fine without that across a WCF SERVICE. The problem is that I really want those connected objects set up through navigation.
基本上代码是一个复杂的对象返回:
Basically the code is a complex object return:
public teCIF getCif(int aCifId)
{
using (CIFContainer context = GetCifContext())
{
var thing = context.teCIFs
.Include("Product_TYPE")
.FirstOrDefault(i => i.CIF_ID == aCifId);
return thing;
}
}
现在奇怪的是,这会工作得很好当我注释掉包含语句。这就像被发送过来的WCF服务的复杂类型不象include语句,只是说:不,不打算做
Now the weird thing is that this will work JUST FINE when I comment out the include statement. It is like the complex type being sent over the WCF service does not like the include statement and just says: "nope, not going to do that".
有关引用我我在相当多的,因为它已经破解复杂的对象是从数据库(略)一T4生成的对象:
For reference my Complex Object I have already hacked at quite a bit as it is a T4 generated object from a database (abbreviated):
[Serializable]
public partial class teCIF
{
public int CIF_ID { get; set; }
public string CUSTOMER_NAME { get; set; }
public string SITE_NAME { get; set; }
[System.Xml.Serialization.XmlIgnore]
public int PRODUCT_TYPE_ID { get; set; }
public virtual tlPRODUCT_TYPE Product_TYPE { get; set; }
}
更新链接copmplex项目:
[Serializable]
public partial class tlPRODUCT_TYPE
{
public tlPRODUCT_TYPE()
{
this.teCIFs = new HashSet<teCIF>();
}
[System.Xml.Serialization.XmlIgnore]
public int PRODUCT_TYPE_ID { get; set; }
public string VALUE { get; set; }
[System.Xml.Serialization.XmlIgnore]
public virtual ICollection<teCIF> teCIFs { get; set; }
}
我曾尝试删除的属性,但还没有与'数据成员搞砸类型WCF喜欢。我只是不明白为什么,因为我已经发誓我在过去的实体版本4做过这个复杂类型的与其他复杂类型的导航属性不起作用。
I have tried removing attributes but have not yet messed with the 'data member' type that WCF likes. I just don't get why this does not work as I have sworn I have done this in the past Entity Version 4 with complex types with navigation properties related to other complex types.
推荐答案
好吧,其实我接到了一个朋友的帮助,但想通这可能想出其他人,所以我要回答这个问题,因为它可以帮助别人。我不得不添加自定义属性,我做了一个类确定循环引用。基本上指针到导航不知何故得到使用WCF的时候输了,但人很好,当没有连接到服务。因为我希望我的服务是托管使用WCF,不只是客户端调用直接使用实体V6的方法这是不好的。
Okay so I actually got help from a friend but figured that this could come up for others so I should answer the question as it may help someone else. I had to add a custom attribute that I make a class for that determines cyclic references. Basically the pointers to the navigation were somehow getting lost when using WCF, but were fine when not hooked up to a service. This is not good as I want my service to be hosting the methods using WCF, not just client calls directly using Entity V6.
[ServiceContract]
public interface ICifService
{
[OperationContract]
[CyclicReferencesAware(true)]
teCIF getCif(int aCifId);
}
实现类的工作原理是这样的:
The implementation class works like this:
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Runtime.Serialization;
using System.Xml;
using System.Collections.Generic;
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Method)]
public class CyclicReferencesAwareAttribute : Attribute, IContractBehavior, IOperationBehavior
{
private readonly bool _on = true;
public CyclicReferencesAwareAttribute(bool on)
{
_on = on;
}
public bool On
{
get { return _on; }
}
#region IOperationBehavior Members
void IOperationBehavior.AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
void IOperationBehavior.ApplyClientBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.ClientOperation clientOperation)
{
CyclicReferencesAwareContractBehavior.ReplaceDataContractSerializerOperationBehavior(operationDescription, On);
}
void IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
{
CyclicReferencesAwareContractBehavior.ReplaceDataContractSerializerOperationBehavior(operationDescription, On);
}
void IOperationBehavior.Validate(OperationDescription operationDescription)
{
}
#endregion
#region IContractBehavior Members
void IContractBehavior.AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
void IContractBehavior.ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
CyclicReferencesAwareContractBehavior.ReplaceDataContractSerializerOperationBehaviors(contractDescription, On);
}
void IContractBehavior.ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
{
CyclicReferencesAwareContractBehavior.ReplaceDataContractSerializerOperationBehaviors(contractDescription, On);
}
void IContractBehavior.Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
}
#endregion
}
public class CyclicReferencesAwareContractBehavior : IContractBehavior
{
private const int MaxItemsInObjectGraph = 2147483647;
private const bool IgnoreExtensionDataObject = false;
private bool _on;
public CyclicReferencesAwareContractBehavior(bool on)
{
_on = on;
}
#region IContractBehavior Members
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
ReplaceDataContractSerializerOperationBehaviors(contractDescription, _on);
}
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
{
ReplaceDataContractSerializerOperationBehaviors(contractDescription, _on);
}
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
}
internal static void ReplaceDataContractSerializerOperationBehaviors(ContractDescription contractDescription, bool on)
{
foreach (var operation in contractDescription.Operations)
{
ReplaceDataContractSerializerOperationBehavior(operation, on);
}
}
internal static void ReplaceDataContractSerializerOperationBehavior(OperationDescription operation, bool on)
{
if (operation.Behaviors.Remove(typeof(DataContractSerializerOperationBehavior)) || operation.Behaviors.Remove(typeof(ApplyCyclicDataContractSerializerOperationBehavior)))
{
operation.Behaviors.Add(new ApplyCyclicDataContractSerializerOperationBehavior(operation, MaxItemsInObjectGraph, IgnoreExtensionDataObject, on));
}
}
#endregion
}
internal class ApplyCyclicDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior
{
private readonly int _maxItemsInObjectGraph;
private readonly bool _ignoreExtensionDataObject;
private readonly bool _preserveObjectReferences;
public ApplyCyclicDataContractSerializerOperationBehavior(OperationDescription operationDescription, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences)
: base(operationDescription)
{
_maxItemsInObjectGraph = maxItemsInObjectGraph;
_ignoreExtensionDataObject = ignoreExtensionDataObject;
_preserveObjectReferences = preserveObjectReferences;
}
public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
{
return new DataContractSerializer(type, name, ns, knownTypes, _maxItemsInObjectGraph, _ignoreExtensionDataObject, _preserveObjectReferences, null /*dataContractSurrogate*/);
}
public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
{
return new DataContractSerializer(type, name, ns, knownTypes, _maxItemsInObjectGraph, _ignoreExtensionDataObject, _preserveObjectReferences, null /*dataContractSurrogate*/);
}
}
有一次,我在我的接口应用这个属性的任何操作我的服务,它的任何复杂类型的罚款。
Once I applied this attribute to any Operation in my interface for my service, it worked fine for any complex type.
这篇关于在WCF中使用时,“包括”与实体版本6语法复杂的对象将不会返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!