当POCO具有IsReference = True属性时,序列化EF代理 [英] Serialize EF Proxy when POCO has IsReference = true Attribute

查看:153
本文介绍了当POCO具有IsReference = True属性时,序列化EF代理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


当使用DataContractSerializer与ProxyContractResolver时,我得到以下内容:


类型为System.Data的IsReference设置。 Entity.DynamicProxies.MyType_59A83378572C10D0B31B6892FB6C3E7428C4BA214322C7A77BD5E1EB19E529CA''为'False',但父类My.Namespace.MyType的设置与True相同。派生类型必须具有与IsReference相同的值作为基本类型。更改类型的设置


似乎EF代理生成器不符合IsReference属性,我在POCO上需要否则我会因为相互引用而结束堆栈溢出)。



在这种情况下,是否有任何机制来序列化EF Proxy?如何?

解决方案

我刚做了以下非常简单的例子, ProxyDataContractResolver 如预期的 - 具有循环的代理实体的图被正确序列化。

  using System; 
使用System.Collections.Generic;
使用System.Data.Entity;
使用System.Data.Objects;
使用System.IO;
使用System.Linq;
使用System.Runtime.Serialization;

命名空间CFSerialization
{
类程序
{
static void Main(string [] args)
{
using var context = new Context())
{
context.Database.Delete();
context.Database.CreateIfNotExists();

context.Masters.Add(new Master
{
Name =abc,
Details = new List< Detail>
{
new Detail {Name =a},
new Detail {Name =b},
new Detail {Name =c}
}
});
context.SaveChanges();
}

使用(var context = new Context())
{
//这将获得代理的Master
var master = context.Masters。第一();

var serializer = new DataContractSerializer(typeof(Master),new DataContractSerializerSettings()
{
DataContractResolver = new ProxyDataContractResolver()
});

使用(var stream = new MemoryStream())
{
//这也将延迟加载所有细节
serializer.WriteObject(stream,master);
stream.Seek(0,SeekOrigin.Begin);
var newMaster =(Master)serializer.ReadObject(stream);
}
}
}
}

[DataContract(IsReference = true)]
public class Master
{
[DataMember]
public int Id {get;组; }
[DataMember]
public string Name {get;组; }
[DataMember]
public virtual ICollection< Detail>细节{get;组;
}

[DataContract(IsReference = true)]
public class Detail
{
[DataMember]
public int Id {get ;组; }
[DataMember]
public string Name {get;组; }
[DataMember]
public virtual Master Master {get;组; }
}

public class上下文:DbContext
{
public DbSet< Master>大师{get;组; }
}
}

您的模型中必须有更复杂的东西打破功能 - 所有您的实体标有 DataContract(IsReference = true)



注意:我测试了在.NET 4.5中。


How can I serialize an Entity Framework Code First Proxy when the class it is proxying is decorated with DataContractAttribute(IsReference = true)?

When using DataContractSerializer with ProxyContractResolver, I get the following:

The IsReference setting for type 'System.Data.Entity.DynamicProxies.MyType_59A83378572C10D0B31B6892FB6C3E7428C4BA214322C7A77BD5E1EB19E529CA' is 'False', but the same setting for its parent class 'My.Namespace.MyType' is 'True'. Derived types must have the same value for IsReference as the base type. Change the setting on type

It seems that the EF Proxy Generator is not respecting the IsReference attribute, which I do need on the POCO (otherwise I end up with a stack overflow due to mutual referencing).

Is there any mechanism at all to serialize an EF Proxy under these circumstances? How?

解决方案

I just did following very simple example and ProxyDataContractResolver works as expected - graph of proxied entities with cycles was correctly serialized.

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Objects;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;

namespace CFSerialization
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var context = new Context())
            {
                context.Database.Delete();
                context.Database.CreateIfNotExists();

                context.Masters.Add(new Master
                    {
                        Name = "abc",
                        Details = new List<Detail>
                            {
                                new Detail { Name = "a" },
                                new Detail { Name = "b" },
                                new Detail { Name = "c" }
                            }
                    });
                context.SaveChanges();
            }

            using (var context = new Context())
            {
                // This will get proxied Master
                var master = context.Masters.First();

                var serializer = new DataContractSerializer(typeof(Master), new DataContractSerializerSettings()
                    {
                        DataContractResolver = new ProxyDataContractResolver()
                    });

                using (var stream = new MemoryStream())
                {
                    // This will also lazy load all details
                    serializer.WriteObject(stream, master);
                    stream.Seek(0, SeekOrigin.Begin);
                    var newMaster = (Master)serializer.ReadObject(stream);
                }
            }
        }
    }

    [DataContract(IsReference=true)]
    public class Master
    {
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public virtual ICollection<Detail> Details { get; set; }
    }

    [DataContract(IsReference=true)]
    public class Detail 
    {
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public virtual Master Master { get; set; }
    }

    public class Context : DbContext
    {
        public DbSet<Master> Masters { get; set; }
    }
}

There must be something more complicated in your model to break the functionality - are all your entities marked with DataContract(IsReference=true)?

Note: I tested it in .NET 4.5.

这篇关于当POCO具有IsReference = True属性时,序列化EF代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆