如果在实体框架中使用延迟加载,如何序列化实体? [英] How to serialize entity if using lazy loading in entity framework?

查看:108
本文介绍了如果在实体框架中使用延迟加载,如何序列化实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始学习实体框架,并且面临与生成的模型的序列化有关的问题.我有一个与国家和州具有一对多关系的表,因为一个国家有许多州.我使用的是数据库优先方法,当我使用实体框架创建实体时,Country类具有ICollection的一个属性.我阅读并发现这是导航属性.首先让我显示生成的类,如下所示:

I just started to learn entity framework and i am facing the problem related to serialization of generated Models. I have tables with one to many relation which are Country and State as one country have many states. I am using the DB first approach and when i create the entities using Entity Framework, the class Country has one property of ICollection. I read and found that this is the navigation property. Let me show the generated class first which is below:

//这是生成的类.

 public class Country
    {
        public Country()
        {
                States = new HashSet<States>();
        }
        public int Id { get; set; }
        public string ContryCode  { get; set; } 
        public string ContryName  { get; set; }    
        public virtual ICollection<States> States{ get; set; }

    }

我生成了模型,然后继续前进.然后,当我通过ajax请求获取国家/地区"列表时,出现了序列化的问题.我在Google上搜索,发现了一些术语,例如延迟加载,渴望加载和n + 1问题.我详细阅读了.我找到了一个关闭延迟加载的解决方案.现在的问题是我该如何通过延迟加载序列化我的模型?

I generated Models and then i step forwarded. Then i got the problem of serialization when i request via ajax to get the list for Country. I googled and found some terms like lazy loading, eager loading and n+1 problem. I read about it in detail. I found a solution which was turning off the lazy loading. Now the question is How i can serialize my Model with lazy loading?

我创建了MetaData类,并使用了诸如ignoreXml等属性,但没有任何帮助.顺便说一句,我正在使用Asp.Net MVC 5,我想序列化带有延迟加载的模型.有人可以解释吗?

I have created MetaData class and use some attribute like ignoreXml etc but nothing helped. By the way i am using Asp.Net MVC 5 and i want to serialize my Model with lazy loading. Can any one explain?

推荐答案

使用延迟加载时,将推迟执行,直到实际需要该属性的值为止.您可能会遇到错误,因为在访问该属性时上下文已被处置.请考虑以下情形:

When you use lazy loading, execution is deferred until the value of the property is actually needed. You are probably encountering an error because the context has been disposed by the time the property is accessed. Consider the following scenario:

  • 您有一个名为Country的对象,该对象具有一个名为States的延迟加载属性.
  • 您是从上下文中获取此对象的.
  • 上下文已处理.
  • 您调用States属性.
  • 该物业正在寻找其来源.
  • 因为上下文已被处理"而引发错误.
  • You have an object called Country with a lazy-loaded property called States.
  • You get this object from a context.
  • The context is disposed.
  • You call the States property.
  • The property goes looking for the context it came from.
  • An error is thrown because "the context has been disposed".

代码示例:

using(var context = new SomeEntityContext())
{
     var country = context.Countries.First();
}

//This will throw an error because the context was disposed of.
var states = country.States; 

序列化器也会抛出错误,因为它将遍历对象的属性,它将找到States并尝试获取其值.

The serializer would also throw an error because it will go through the properties of the object, it will find States and it will try to get its value.

即使上下文仍然存在,您也可能在序列化过程中遇到带有导航属性的循环.这是因为两个对象相互引用.请考虑以下情形:

Even if the context is still alive, you could run into a loop with navigational properties during serialization. this is because both objects hold a reference to each other. Consider the following scenario:

  • 您有一个名为Country的对象,该对象具有一个名为States的延迟加载属性.
  • 序列化程序尝试对类型为Country的对象进行序列化.
  • 它读取States集合.
  • 它将尝试序列化State类型的每个对象.
  • 它读取类型为Country的属性.
  • 它尝试序列化Country类型的对象.
  • 它读取States集合.
  • 它将尝试序列化State类型的每个对象.
  • 它读取类型为Country的属性.
  • 它读取States集合.
  • 它将尝试序列化State类型的每个对象.
  • 它读取类型为Country的属性.
  • 它读取States集合.
  • 它将尝试序列化State类型的每个对象.
  • 它读取类型为Country的属性.
  • ....(无休止的循环,至少直到耗尽堆栈帧为止).
  • You have an object called Country with a lazy-loaded property called States.
  • The serializer attempts to serializer the object of type Country.
  • It reads the States collection.
  • It attempts to serialize every object of type State.
  • It reads a property of type Country.
  • It attempts to serialize the object of type Country.
  • It reads the States collection.
  • It attempts to serialize every object of type State.
  • It reads a property of type Country.
  • It reads the States collection.
  • It attempts to serialize every object of type State.
  • It reads a property of type Country.
  • It reads the States collection.
  • It attempts to serialize every object of type State.
  • It reads a property of type Country.
  • .... (endless loop, well, at least until you run out of stack frames).

或者,您可以创建一个自定义的序列化程序,该序列化程序将避免导航属性的陷阱,但这可能比它值得的工作还要多.此方法最适合序列化版本与对象明显不同的情况.

Alternatively, you can create a custom serializer that will avoid the pitfalls of navigational properties, but that is probably more work than it's worth. This approach is best suited for situations where the serialized version differs significantly from the object.

这就是为什么最好使用数据传输对象(DTO)的原因.将数据映射到该对象,然后通过电线发送.如果您使结构尽可能相似,则那里的组件可以为您完成映射.

This is why you are better off using a Data Transfer Object (DTO). Map the data to this object and send that over the wire. There are components out there that can do the mapping for you, if you keep the structures as similar as possible.

签出AutoMapper: http://automapper.org/

Check out AutoMapper: http://automapper.org/

这篇关于如果在实体框架中使用延迟加载,如何序列化实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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