实体框架与序列化对象的一个​​一对多的关系(Serialization of Entity Fram

2019-06-18 15:29发布

我试图使用与EF代码第一次和Web API。 我没有任何问题,直到我进入序列化许多一对多的关系。 当我尝试下面我收到以下错误消息,执行以下Web API方法:

public class TagsController : ApiController
{

        private BlogDataContext db = new BlogDataContext();

        // GET api/Tags
        public IEnumerable<Tag> GetTags()
        {
            return db.Tags.AsEnumerable();
        }
}

我得到以下错误:

“System.Data.Entity.DynamicProxies.Tag_FF17EDDE6893000F7672649A39962DB0CA591C699DDB73E8C2A56203ED7C7B6D”数据合同名称“Tag_FF17EDDE6893000F7672649A39962DB0CA591C699DDB73E8C2A56203ED7C7B6D: http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies ”预计不会。 考虑使用DataContractResolver或不添加静态已知的已知类型的列表中的任何类型 - 例如,通过使用KnownTypeAttribute属性或将它们添加到已知类型传递给DataContractSerializer的列表。

我看过一些文章SO( 第1条 , 第2条 ),该解决方法是添加以下属性:

[DataContract(IsReference =真)]

但这没有影响。 还使用[IgnoreDataMember]不具有效果。 这似乎工作的唯一选择是Configuration.ProxyCreationEnabled设置为false。 这是我唯一的选择吗? 我缺少的东西吗?

样品POCO对象:

标签

[DataContract(IsReference = true)]
public class Tag
{
        public Tag()
        {
            this.Blogs = new HashSet<Blog>();
        }

        [Key]
        [DataMember]
        public int Id { get; set; }

        [DataMember]
        public string Name { get; set; }

        [IgnoreDataMember]
        public virtual ICollection<Blog> Blogs { get; set; }
}

博客

[DataContract(IsReference = true)]
public class Blog
{
    public Blog()
    {
        this.Tags = new HashSet<Tag>();
    }

    [Key]
    [DataMember]
    public int Id { get; set; }

    [DataMember]
    public string Name { get; set; }

    [IgnoreDataMember]
    public virtual ICollection<Tag> Tags { get; set; }
}

Answer 1:

当你看到一个物体,如:

System.Data.Entity.DynamicProxies.Tag_FF17EDDE6893000F7672649A39962DB0CA591C699DDB73E8C2A56203ED7C7B6D

这是一个代理的运行时EF生成的版本是什么通常会被认为是POCO对象。

因为它跟踪时的对象发生了变化,所以当你调用实体框架已经创造了这个对象.SaveChanges()它可以优化该怎么做。 这样做的缺陷是你没有实际使用您定义的特定对象,因此数据合同和框架(Json.net)不能使用他们,因为他们将原来的POCO对象。

要返回这个对象,你有两个选择(ATM)防止EF:

首先, 试着在你的DbContext关闭代理对象的创建 。

DbContext.Configuration.ProxyCreationEnabled = false;

这将完全禁用每一个查询到具体的DbContext的创建代理对象。 (这不会影响到ObjectContext的缓存的对象)。

其次,使用的EntityFramework 5.0+与AsNoTracking() (ProxyCreationEnabled是在EF 5.0仍可作为孔)

你也应该能够

DbContext.Persons.AsNoTracking().FirstOrDefault();

要么

DbContext.Persons.
  .Include(i => i.Parents)
  .AsNoTracking()
  .FirstOrDefault();

而不是禁止全局代理创建为的DbContext,这只是将其关闭每次查询。 (这影响在ObjectContext的缓存的对象,它是不缓存)



Answer 2:

我想离开的代理创建inteact,发现使用ProxyDataContractResolver似乎解决这个问题对我来说。 请参阅MSDN关于如何在WCF中,这是不完全的WebAPI使用它的引用,但应该让你沿着正确的道路去。



文章来源: Serialization of Entity Framework objects with One to Many Relationship