我对这个问题感到不满。我确实在互联网上找到了一些关于它的内容,但不是一个明确的答案。我的问题:
我必须在MVC3 Web应用程序的Model部分中编写类: ParentClass和ChildClass 在ParentClass上有一个属性类型为List
的子属性我使用了EF Code First,它在数据库中为我整齐地生成了父表和子表。
现在我需要一个REST服务,它返回一个List或一个ParentClass。
当我从ParentClass中删除属性Children时没有问题。但随着孩子们在那里,我不断收到错误。
错误:"The type System.Data.Entity.DynamicProxies.ParentClass_A0EBE0D1022D01EB84B81873D49DEECC60879FC4152BB115215C3EC16FB8003A was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."}
一些代码:
类:
public class ParentClass
{
public int ID { get; set; }
public string Name {get;set;}
public virtual List<ChildrenClass> Children { get; set; }
}
public class ChildrenClass
{
public int ID { get; set; }
public string MyProperty { get; set; }
}
服务:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class MyService
{
static MyContext db;
public MyService() { db = new MyContext(); }
[WebGet(UriTemplate = "")]
public List<ParentClass> GetParents()
{
var result = db.Parents.ToList();
return result;
}
当我打电话给这项服务时,我不会得到结果。我做错了什么?
答案 0 :(得分:12)
我不得不在上下文配置中使用DisableProxyCreation:
[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;
}
}
这对我来说很好。
答案 1 :(得分:0)
它似乎是为您的POCO序列化代理类,我的第一个建议是使用proxydatacontractresolver:http://msdn.microsoft.com/en-us/library/system.data.objects.proxydatacontractresolver.aspx。
此外,我还会在加载通过网络服务发送的数据时明确说明事情......即
将父类更改为
public class ParentClass
{
public int ID { get; set; }
public string Name {get;set;}
public List<ChildrenClass> Children { get; set; }
}
更改您的内容以关闭延迟加载: Disable lazy loading by default in Entity Framework 4
并在返回通过网络发送的数据时明确指定要加载的内容。
[WebGet(UriTemplate = "")]
public List<ParentClass> GetParents()
{
var result = db.Parents.Include("Children").ToList();
return result;
}
请查看以下答案:Entity Framework Code First - Eager Loading not working as expected?以获取更高级的包含电话。
另外,根据经验提供的建议,我不会通过网络返回您的数据类,因为它们构成了Web服务的使用者的合同。您最好使用另一组类来将数据值映射到。
这样,如果数据类发生更改,除非明确要求,否则不必更改Web服务客户端。
如果您希望在Parent或Child类中有1000行,则使用分页很重要,否则您最终会选择N + 1,请参阅:What is SELECT N+1?。
答案 2 :(得分:0)
在某些情况下,一个简单的解决方案是使用包装类,以便公开的所有属性都是已知类型。
通常,您不会在控制器类中使用ObjectContext或DbContext,因此在早期层(业务层或服务层)中,您可以从来自DB的对象快速转换为ViewModel样式对象,类似你在MVC应用程序中做了什么,但不是将它们传递给View,而是将它们返回给调用者。
也许你不能在所有情况下使用它,但通常这是一个可行的妥协。