Entity framework WCF&x2B;带有FK的EF返回对象
我面临以下问题:我有一个ProductOrder类,它将ProductId作为Product类的外键。当我调用以下方法时:Entity framework WCF&x2B;带有FK的EF返回对象,entity-framework,wcf,Entity Framework,Wcf,我面临以下问题:我有一个ProductOrder类,它将ProductId作为Product类的外键。当我调用以下方法时: public IEnumerable<ProductOrder> GetOrders() { return OddzialDb.ProductOrders; } 但当它到达客户机时,发现它与产品之间没有空的关联(只包括ProductId)。在DbContext中,我设置了 base.Configuration.ProxyCreationEna
public IEnumerable<ProductOrder> GetOrders()
{
return OddzialDb.ProductOrders;
}
但当它到达客户机时,发现它与产品之间没有空的关联(只包括ProductId)。在DbContext中,我设置了
base.Configuration.ProxyCreationEnabled = false;
base.Configuration.LazyLoadingEnabled = false;
在由EF ProductOrder类自动生成的WCF服务端上,如下所示:
public partial class ProductOrder
{
public int Id { get; set; }
public Nullable<int> ProductId { get; set; }
public int Quantity { get; set; }
public virtual Product Product { get; set; }
}
公共部分类ProductOrder
{
公共int Id{get;set;}
公共可为空的ProductId{get;set;}
公共整数数量{get;set;}
公共虚拟产品产品{get;set;}
}
如果它断开与外键关联的表的连接,会发生什么情况?使您的关系成为虚拟关系,如示例所示:
public class ProductOrder
{
public int Id { get; set; }
public virtual Product Product { get; set; }
public int ProductId { get; set; }
}
通过将关系变为虚拟关系,实体框架将生成ProductOrder
类的代理,该代理将包含产品的引用
为确保其正常工作,产品
还必须包含对产品订单
的引用:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ProductOrder> ProductOrders { get; set; }
}
在您的WCF应用程序上,添加以下类,该类将允许代理序列化:
public class ApplyDataContractResolverAttribute : Attribute, IOperationBehavior
{
public ApplyDataContractResolverAttribute()
{
}
public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
{
}
public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy)
{
DataContractSerializerOperationBehavior dataContractSerializerOperationBehavior =
description.Behaviors.Find<DataContractSerializerOperationBehavior>();
dataContractSerializerOperationBehavior.DataContractResolver =
new ProxyDataContractResolver();
}
public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch)
{
DataContractSerializerOperationBehavior dataContractSerializerOperationBehavior =
description.Behaviors.Find<DataContractSerializerOperationBehavior>();
dataContractSerializerOperationBehavior.DataContractResolver =
new ProxyDataContractResolver();
}
public void Validate(OperationDescription description)
{
// Do validation.
}
}
尝试OddzialDb.ProductOrders.Include(po=>po.Product.First().Product.Name;我得到循环引用。您可能需要在序列化之前投影结果。我已经尝试过包含,在这种情况下,我收到循环引用错误。当客户端使用WCF服务时,它会自动生成类,如Product等。使用WCF
,使用第二种方法会更好。我自己从来没有让它以另一种方式正常工作。就EF的WCF服务而言,Product和ProductOrders都使用虚拟关键字相互引用。但是,只要您使用延迟加载并使所有关系完全可序列化
,它将只通过网络发送所有关系。我已更改为base.Configuration.LazyLoadingEnabled=true。没有发现好转。
Configuration.LazyLoadingEnabled = true;
Configuration.ProxyCreationEnabled = true;
public class ApplyDataContractResolverAttribute : Attribute, IOperationBehavior
{
public ApplyDataContractResolverAttribute()
{
}
public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
{
}
public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy)
{
DataContractSerializerOperationBehavior dataContractSerializerOperationBehavior =
description.Behaviors.Find<DataContractSerializerOperationBehavior>();
dataContractSerializerOperationBehavior.DataContractResolver =
new ProxyDataContractResolver();
}
public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch)
{
DataContractSerializerOperationBehavior dataContractSerializerOperationBehavior =
description.Behaviors.Find<DataContractSerializerOperationBehavior>();
dataContractSerializerOperationBehavior.DataContractResolver =
new ProxyDataContractResolver();
}
public void Validate(OperationDescription description)
{
// Do validation.
}
}
[OperationContract]
[ApplyDataContractResolver]
[FaultContract(typeof(AtcWcfEntryNotFoundException))]
Case GetSingleByCaseNumber(int number);