实体框架与序列化对象的一个​​一对多关系 [英] Serialization of Entity Framework objects with One to Many Relationship

查看:128
本文介绍了实体框架与序列化对象的一个​​一对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用带有code首先和Web API EF。我没有任何问题,直到我进入序列许多一对多的关系。当我尝试执行以下Web API方法下面我收到以下错误信息:

 公共类TagsController:ApiController
{        私人BlogDataContext DB =新BlogDataContext();        //获取API /标签
        公共IEnumerable的<标记和GT; GetTags()
        {
            返回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(<一个href=\"http://stackoverflow.com/questions/11315311/using-navigation-properties-in-entity-framework-$c$c-first\">article 1 ,第2条)的修复是添加以下属性:


  

[DataContract(IsReference = TRUE)]


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

样品POCO对象:

代码

  [DataContract(IsReference =真)]
公共类标签
{
        公共标签()
        {
            this.Blogs =新的HashSet&LT;博客&GT;();
        }        [键]
        [数据成员]
        公众诠释标识{搞定;组; }        [数据成员]
        公共字符串名称{;组; }        [IgnoreDataMember]
        公共虚拟的ICollection&LT;博客&GT;博客{搞定;组; }
}

博客

  [DataContract(IsReference =真)]
公共类博客
{
    公共博客()
    {
        this.Tags =新的HashSet&LT;吊牌及GT;();
    }    [键]
    [数据成员]
    公众诠释标识{搞定;组; }    [数据成员]
    公共字符串名称{;组; }    [IgnoreDataMember]
    公共虚拟的ICollection&LT;标记和GT;标签{搞定;组; }
}


解决方案

当你看到这样一个对象:


  

System.Data.Entity.DynamicProxies.Tag_FF17EDDE6893000F7672649A39962DB0CA591C699DDB73E8C2A56203ED7C7B6D


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

因为它跟踪时的对象发生了变化,所以当你调用 .SaveChanges()它可以优化做什么

实体框架创建该对象。这样做的缺陷是你没有实际使用您定义的特定对象,因此数据合同和框架(Json.net)不能用他们,因为他们将原来的POCO对象。

这回该对象prevent EF你有两个选择(ATM):

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

  DbContext.Configuration.ProxyCreationEnabled = FALSE;

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

其次,使用的EntityFramework 5.0 + 使用 AsNoTracking()
(ProxyCreationEnabled仍然可用在EF 5.0为好)

您也应该能够

  DbContext.Persons.AsNoTracking()FirstOrDefault()。

  DbContext.Persons。
  .INCLUDE(I =&GT; i.Parents)
  .AsNoTracking()
  .FirstOrDefault();

代替的全球的禁用代理创建为的DbContext,这只是将其关闭每次查询。 (这的 DOES 的影响的缓存的对象ObjectContext中,它是不缓存)

I am attempting to use EF with Code First and the Web API. I don't have any problems until I get into serializing Many-to-Many relationships. When I attempt to execute the following web api method below I get the following error message:

public class TagsController : ApiController
{

        private BlogDataContext db = new BlogDataContext();

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

I get the following error:

'System.Data.Entity.DynamicProxies.Tag_FF17EDDE6893000F7672649A39962DB0CA591C699DDB73E8C2A56203ED7C7B6D' with data contract name 'Tag_FF17EDDE6893000F7672649A39962DB0CA591C699DDB73E8C2A56203ED7C7B6D:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

I have read some SO articles (article 1, article 2) that the fix is to add the following attribute:

[DataContract (IsReference=true)]

but this has had no effect. Also using [IgnoreDataMember] does not have an effect. The only option that does seem to work is to set Configuration.ProxyCreationEnabled to false. Is this my only option? Am I missing something?

Sample POCO objects:

Tag

[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; }
}

Blog

[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; }
}

解决方案

When you see an object like:

System.Data.Entity.DynamicProxies.Tag_FF17EDDE6893000F7672649A39962DB0CA591C699DDB73E8C2A56203ED7C7B6D

It is a runtime EF Generated version of a proxy to what would normally be considered a POCO object.

Entity Framework has created this object because it tracks when the objects has changed so when you call .SaveChanges() it can optimize what to do. The downfall of this is that you aren't actually using the specific object you defined, thus Data Contracts and Frameworks (Json.net) cannot use them as they would your original POCO object.

To Prevent EF from returning this object you have two choices (ATM):

First, Try turning off Proxy object creation on your DbContext.

DbContext.Configuration.ProxyCreationEnabled = false;

This will completely disable the create of Proxy objects for every query to the specific DbContext. (This does not affect the cached object in the ObjectContext).

Secondly, use EntityFramework 5.0+ with AsNoTracking() (ProxyCreationEnabled is still available in EF 5.0 as well)

You should also be able to

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

or

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

Instead of globally disabling proxy creation for the DbContext, this only turns it off per query. (This DOES affect the cached object in the ObjectContext, it is not cached)

这篇关于实体框架与序列化对象的一个​​一对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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