WebApi with EF Code First generates error when having parent child relation

我的未来我决定 提交于 2019-11-29 06:13:14
Mounhim

I had to DisableProxyCreation in the context configuration:

[OperationContract] 
[WebGet(UriTemplate = "")] 
public List<ParentClass> GetParents() 
{ 
     using (DBContext context = new DBContext()) 
     {
         context.Configuration.ProxyCreationEnabled = false; 
         List<ParentClass> parents = context.Parents
             .Include("Children") 
             .ToList();
         return parents; 
      }
}

This worked out for me fine.

JTew

It seems to be serialising the proxy classes for your POCOs, my first recommendation would be to use the proxydatacontractresolver: http://msdn.microsoft.com/en-us/library/system.data.objects.proxydatacontractresolver.aspx.

Also I would work on having things spelt out explicitly when loading data for sending over web service ... i.e.

Change Parent class to

public class ParentClass
{
    public int ID { get; set; }
    public string Name {get;set;}
    public List<ChildrenClass> Children { get; set; }

}

Alter your content to turn off lazy loading: Disable lazy loading by default in Entity Framework 4

And explicitly specify what you want to load when returning data being sent over the wire.

[WebGet(UriTemplate = "")]
public List<ParentClass> GetParents()
{
    var result = db.Parents.Include("Children").ToList();
    return result;

}

Have a look at the following answer: Entity Framework Code First - Eager Loading not working as expected? for more advanced Include calls.

Also a piece of advice from experience, I wouldn't return your data classes over the wire as they form a contract for the consumer of your web service. You are best to have another set of classes that you map your data values into.

That way if your data classes change, you don't have to change the web service client unless explicitly required.

And using paging is important if you are expecting 1000's of rows in the Parent or Child classes otherwise you end up with N+1 select, see : What is SELECT N+1?.

In some situations a simple solution is to use a wrapper class so that all the properties exposed are known types.

Usually you won't be using an ObjectContext or a DbContext in your controller classes anyway so in an earlier layer (Business or Service layer) you can do a quick translation from the objects coming from the DB into ViewModel style objects, similar to what you'd do in an MVC app, but instead of passing them on to a View you return them to the caller.

Maybe you can't use it in all cases, but often it's a workable compromise.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!