简体   繁体   English

在实体框架4.0中反序列化问题

[英]Deserializing Issue in Entity Framework 4.0

I am working on an appliction, using Entity Framework 4.0. 我正在使用Entity Framework 4.0开发一个应用程序。 and WCF. 和WCF。

I am returning list of objects say (Employees) 我正在返回对象列表说(员工)

and the navigational property of that object is say(Departments) 并说该对象的导航属性(部门)

and Department has further a navigational property (Branch) 和部门还有一个航海财产(分公司)

I am including everything as 我把一切都包括在内

Employees.include("Departments.Branch");

Now th issue all those departments whose Branch is same, is set to null(except the first one) upon deserializing on WCF. 现在发布所有那些Branch相同的部门,在WCF上反序列化时设置为null(第一个除外)。

I need to use the branch for some binding purposes, kindly guide me how should i get rid of this problem. 我需要使用分支进行一些绑定,请指导我如何摆脱这个问题。

This is the screenshot of the entities 这是实体的屏幕截图 在此输入图像描述

It may be that the data is not being loaded before serialisation, but when you debug on the server side, lazy loading causes the data to be loaded. 可能是在序列化之前没有加载数据,但是当您在服务器端进行调试时,延迟加载会导致数据被加载。

A couple of things that you could try. 你可以试试几件事。

This will force the query to run: 这将强制查询运行:

Employees.include("Departments.Branch").ToList();

This will explicitly load the entities: 这将显式加载实体:

context.Entry(Employees).Reference(u => u.Departments.Branch).Load();

You could try to use Entity Framework profiler and see whether generated query is having valid data. 您可以尝试使用Entity Framework概要分析器并查看生成的查询是否具有有效数据。 http://efprof.com/ http://efprof.com/

From MSDN 来自MSDN

Windows Communication Foundation (WCF) cannot directly serialize or deserialize proxies because the DataContractSerializer can only serialize and deserialize known types, and proxy types are not known types. Windows Communication Foundation(WCF)无法直接序列化或反序列化代理,因为DataContractSerializer只能序列化和反序列化已知类型,而代理类型不是已知类型。 When you need to serialize POCO entities, disable proxy creation or use the ProxyDataContractResolver class to serialize proxy objects as the original POCO entities. 当您需要序列化POCO实体时,请禁用代理创建或使用ProxyDataContractResolver类将代理对象序列化为原始POCO实体。 To disable proxy creation, set the ProxyCreationEnabled property to false. 要禁用代理创建,请将ProxyCreationEnabled属性设置为false。

Beyond that, check if you are using Interoperable Object References ? 除此之外,检查您是否使用互操作对象引用 I would try that as well. 我也会试试。 Follow the instructions here on how to set it up 按照此处有关如何设置的说明进行操作

On your POCO classes + enumerations and structs (all of them that are serialized), you must have the DataContract attribute with IsReference=true: 在POCO类+枚举和结构(所有序列化的结构)上,必须具有IsReference = true的DataContract属性:

[DataContract(Name = "Employee", Namespace = "http://MyNamespace", IsReference=true)]
class Employee
{
    [DataMember(Name="Branch")]
    public Branch _branch = new Branch();
            ... or ...
    [DataMember(Name="Branches")]
    public List<Branch> _branches = new List<Branch>();
}

[DataContract(Name = "Branch", Namespace = "http://MyNamespace", IsReference=true)]
class Branch { ... }

It is the IsReference=true that makes sure that all of the pointers are converted into references during serialization. IsReference = true确保在序列化期间将所有指针转换为引用。 Also make sure your references have a DataMember attribute. 还要确保您的引用具有DataMember属性。

On the POCO-Classes use [DataContract] for the class, [DataMember] for properties, like Bahri Gungor said. 在POCO-Classes上使用[DataContract]作为类, [DataMember]用于属性,如Bahri Gungor所说。 In addition you can write some Methods, which will be called by the Serializer. 此外,您可以编写一些方法,这些方法将由Serializer调用。 Check MSDN for: OnDeserialized OnDeserializing , OnSerialized and OnSerializing 检查MSDN: OnDeserialized OnDeserializingOnSerializedOnSerializing

In WCF-Service you need to use a Attribute, to declare, where you want to return EF-Proxy-Classes. 在WCF服务中,您需要使用Attribute来声明要返回EF-Proxy-Class的位置。

[ApplyDataContractResolver]
public POCO_CLASS GetById(int id){
    // your code here...
}

And the ApplyDataContractResolver looks like: ApplyDataContractResolver看起来像:

public class ApplyDataContractResolverAttribute : Attribute, IOperationBehavior {
    public ApplyDataContractResolverAttribute() {
    }

    public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters) {
    }

    public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy) {
        var dataContractSerializerOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
        dataContractSerializerOperationBehavior.DataContractResolver = new ProxyDataContractResolver();
    }

    public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch) {
        var dataContractSerializerOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
        dataContractSerializerOperationBehavior.DataContractResolver = new ProxyDataContractResolver();
    }

    public void Validate(OperationDescription description) {
        // Do validation.
    }
}

Background is that the WCF serialise with an DataContractSerializer and EF builds Proxy-Classes to track the changes. 背景是带有DataContractSerializer的WCF序列化和EF构建代理类来跟踪更改。

Here a link to MSDN for ProxyDataContractResolver : MSDN 这里是ProxyDataContractResolver MSDN链接: MSDN

Try to use both .Include() on the query to load related objects and the [Include] attribute in the metadata to allow those related objects to be serialized and sent to the client. 尝试在查询上同时使用.Include()来加载相关对象,并在元数据中使用[Include]属性,以允许将这些相关对象序列化并发送到客户端。

This issue (or at least similar) is discussed here 这里讨论了这个问题(或至少类似的问题)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM