实体框架将POCO序列化为JSON
我正在使用EF4.1,我有一个POCO对象,我想序列化为JSON,我读到在使用延迟加载时这样做有问题,但我不确定我是否可以,因为实体框架将POCO序列化为JSON,json,entity-framework,serialization,entity-framework-4.1,Json,Entity Framework,Serialization,Entity Framework 4.1,我正在使用EF4.1,我有一个POCO对象,我想序列化为JSON,我读到在使用延迟加载时这样做有问题,但我不确定我是否可以,因为消息可以包含消息的集合 有没有办法做到这一点?将此类对象序列化为JSON 我的消息对象看起来像: public class Message { [Key] public int Id { get; set; } public int? ParentId { get; set; } public string Title { get; se
消息
可以包含消息
的集合
有没有办法做到这一点?将此类对象序列化为JSON
我的消息
对象看起来像:
public class Message
{
[Key]
public int Id { get; set; }
public int? ParentId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? LastModified { get; set; }
public virtual User User { get; set; }
public virtual Message Parent { get; set; }
public virtual ICollection<Message> Children { get; set; }
}
公共类消息
{
[关键]
公共int Id{get;set;}
public int?ParentId{get;set;}
公共字符串标题{get;set;}
公共字符串内容{get;set;}
public DateTime CreatedAt{get;set;}
公共日期时间?LastModified{get;set;}
公共虚拟用户用户{get;set;}
公共虚拟消息父级{get;set;}
公共虚拟ICollection子项{get;set;}
}
这个怎么样:
- 将您的类标记为
[Serializable]
- 使用JsonSerializer将对象序列化为JSON
- 也许在EF查询中的属性上使用渴望加载
使用Include()加载它。示例linq:
var serializeMe = (from m in MyContext.Message.Include("User") where m.Id == someValue select m).ToList();
这将告诉EF立即加载用户导航属性,而不是延迟加载,那么序列化程序应该不会有问题。问题是循环引用。避免这种情况的一种简单方法是使用Json.Net而不是默认的MVC Json序列化程序。最新版本的Json.Net将使用开箱即用的循环引用序列化对象。关于这个问题的更多信息,让我们分部分来讨论 为什么会发生这种情况? 因为你有虚拟财产。如果您使用的是EF,那么如果您使用的是延迟加载,那么您实际上需要它们。您可以通过以下示例将EF配置为不执行此操作:
context.Configuration.ProxyCreationEnabled = false;
其中context是您的ObjectContext或DbContext。。。假设您使用的是EF。但对于大多数情况,这并不是一个好办法
可能的解决方案
正如我常说的:“没有好的或坏的解决方案,只有不同的方法,这取决于上下文”,也就是说,您可以创建动态对象
如果您只需要序列化一个唯一的对象,您可以这样做
Json(new {@property1=yourObject.property1, @property2=yourObject.property2})
如果您有一个列表,那么您可以这样做:
var list = new List<dynamic>();
foreach(var item in myRepository.GetAll())
{
list.Add(new
{
@property1= item.property1,
@property2= item.property2,
@property3= item.property3
});
}
return Json(list, JsonRequestBehavior.DenyGet);
var list=newlist();
foreach(myRepository.GetAll()中的var项)
{
列表。添加(新)
{
@property1=项目。property1,
@property2=项目。property2,
@property3=项目。property3
});
}
返回Json(列表,JsonRequestBehavior.DenyGet);
我试着让它尽可能的通用。我希望这能帮助别人
致以最诚挚的问候,祝你度过愉快的一天!:) 谢谢你的详细回答,但我恐怕虚拟财产不是这样加载的…@CD:我缺少什么?对于集合和单个属性,
virtual
属性已序列化,非常好:谢谢ReferenceLoopHandling.Ignore
和一个自定义的ContractResolver
完成了这个技巧:-)包括相关的实体解决了我序列化EF对象图时遇到的一个问题,因为我能够从类中有问题的属性中去掉虚拟关键字。谢谢
var list = new List<dynamic>();
foreach(var item in myRepository.GetAll())
{
list.Add(new
{
@property1= item.property1,
@property2= item.property2,
@property3= item.property3
});
}
return Json(list, JsonRequestBehavior.DenyGet);