WCF + EF使用FK返回对象

时间:2015-06-04 15:21:21

标签: entity-framework wcf

我遇到以下问题:我有ProductOrder类,它将ProductId作为Product类的外键。当我调用以下方法时:

public IEnumerable<ProductOrder> GetOrders()
{
      return OddzialDb.ProductOrders;
}

订单与产品相关联,因此我可以写下这样的内容:

OddzialDb.ProductOrders.First().Product.Name;

但是当它到达客户端时,事实证明与Product没有关联,这是null(仅包括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; }
    }

它会丢失与外键关联的表的连接会发生什么?

1 个答案:

答案 0 :(得分:0)

关系虚拟化为示例:

public class ProductOrder
{
    public int Id { get; set; }
    public virtual Product Product { get; set; }
    public int ProductId { get; set; }
}

通过改变您的关系virtual,实体框架将生成ProductOrder类的代理,其中包含Product的引用。

为了确保它有效,Product还必须包含对ProductOrder的引用:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<ProductOrder> ProductOrders { get; set; }
}

DbContext上设置这些变量为真:

Configuration.LazyLoadingEnabled = true;
Configuration.ProxyCreationEnabled = true;

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.
    }
}

然后在您的ServiceContract界面上,将DataAnnotation [ApplyDataContractResolver]权限添加到您的其他注释中,例如[OperationContract],在任何返回实体的方法签名之上:

[OperationContract]
[ApplyDataContractResolver]
[FaultContract(typeof(AtcWcfEntryNotFoundException))]
Case GetSingleByCaseNumber(int number);