Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 3 具有EF代码的WebApi在具有父子关系时首先生成错误_Asp.net Mvc 3_Entity Framework_Rest_Ef Code First_Wcf Web Api - Fatal编程技术网

Asp.net mvc 3 具有EF代码的WebApi在具有父子关系时首先生成错误

Asp.net mvc 3 具有EF代码的WebApi在具有父子关系时首先生成错误,asp.net-mvc-3,entity-framework,rest,ef-code-first,wcf-web-api,Asp.net Mvc 3,Entity Framework,Rest,Ef Code First,Wcf Web Api,我在这个问题上伤了脑筋。我确实在网上找到了一些关于它的信息,但没有一个明确的答案。我的问题是: 我必须在MVC3 web应用程序的模型部分学习以下课程: 父级和子级 在ParentClass上有一个类型为List的属性Children 我首先使用EF代码,它在数据库中为我整洁地生成一个父表和一个子表 现在我需要一个REST服务,它返回一个列表或一个父类 当我从父类中删除属性Children时,没有问题。但在那里的孩子们中,我总是犯错误 错误:“类型System.Data.Entity.Dynam

我在这个问题上伤了脑筋。我确实在网上找到了一些关于它的信息,但没有一个明确的答案。我的问题是:

我必须在MVC3 web应用程序的模型部分学习以下课程: 父级和子级 在ParentClass上有一个类型为List的属性Children

我首先使用EF代码,它在数据库中为我整洁地生成一个父表和一个子表

现在我需要一个REST服务,它返回一个列表或一个父类

当我从父类中删除属性Children时,没有问题。但在那里的孩子们中,我总是犯错误

错误:
“类型System.Data.Entity.DynamicProxies.ParentClass_A0EBE0D1022D01EB84B81873D49DEEC60879FC4152BB115C3EC16FB8003A不是预期的。请使用XmlInclude或SoapInclude属性指定静态未知的类型。”}

一些代码:

课程:

     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; }
}
公共类父类
{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共虚拟列表子项{get;set;}
}
公营儿童班
{
公共int ID{get;set;}
公共字符串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;

    }
[服务合同]
[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
公共类MyService
{
静态MyContext数据库;
public MyService(){db=new MyContext();}
[WebGet(UriTemplate=”“)]
公共列表GetParents()
{
var result=db.Parents.ToList();
返回结果;
}

调用此服务时,我不会得到结果。我做错了什么?

似乎正在序列化POCO的代理类,我的第一个建议是使用proxydatacontractresolver:

此外,我还将致力于在加载通过web服务发送的数据时将事情明确地表达出来

将父类更改为

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

}
公共类父类
{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共列表子项{get;set;}
}
更改内容以关闭延迟加载:

并明确指定在返回通过导线发送的数据时要加载的内容

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

}
[WebGet(UriTemplate=”“)]
公共列表GetParents()
{
var result=db.Parents.Include(“Children”).ToList();
返回结果;
}
看看下面的答案:对于更高级的Include调用

另外一条经验建议是,我不会通过网络返回数据类,因为它们为web服务的消费者形成了一个契约。您最好拥有另一组将数据值映射到其中的类

这样,如果您的数据类发生更改,除非明确要求,否则不必更改web服务客户机


如果您希望父类或子类中有1000行,则使用分页非常重要,否则最终将使用N+1 select,请参见:。

我必须在上下文配置中禁用ProxyCreation:

[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; 
      }
}
[运营合同]
[WebGet(UriTemplate=”“)]
公共列表GetParents()
{ 
使用(DBContext context=new DBContext())
{
context.Configuration.ProxyCreationEnabled=false;
List parents=context.parents
.包括(“儿童”)
.ToList();
返回父母;
}
}

这对我来说很好。

在某些情况下,一个简单的解决方案是使用包装器类,以便公开的所有属性都是已知类型

通常,您不会在控制器类中使用ObjectContext或DbContext,所以在早期的层(业务层或服务层)中也是如此您可以将来自DB的对象快速转换为ViewModel样式的对象,这与您在MVC应用程序中所做的类似,但您不需要将它们传递到视图,而是将它们返回给调用者


也许你不能在所有情况下都使用它,但通常这是一个可行的折衷办法。

我尝试过DataContractResolver,但没有用。disableproxycreation确实有用。但是如果我理解正确,我应该将POCO的填充从数据库中分离出来,并将其与服务中使用的类分开。但这不意味着每个对象都需要被复制,意味着在站点和业务逻辑中使用父类,在服务中使用单独的父类。这不是太多重复代码吗?我们使用DTO和Automapper将我们的资源模型从域模型中分离出来。这有很多优点,包括单独验证和单独/不同t structuresIt为N种不同的用途复制POCO通常是过分的,包括添加工作和维护maps/XLAT。许多开发人员采取的方法是仔细定义POCO一次,然后将其用于数据传输和数据访问,尤其是在较小的项目上。如果有一天这种情况不再发生r工作(模式更改、重构等)然后,应该定义新的POCO,并根据需要执行映射。这种转换/重构根本不会影响web客户端,它只会对类库的.NET使用者造成问题。例如,二进制依赖项。我同意复制POCO会适得其反。使用POCO背后的潜在意图是不同的你应该有一个不同的POCO。根据经验,我知道数据层的类不应该作为数据契约通过网络公开。一旦你改变了数据库层,就推断数据契约已经改变,所有消费客户端也应该改变。因此,重用数据POCO不允许你灵活地对数据进行版本化客户端的ata/服务接口。正是我想要的。你知道禁用此功能有什么缺点吗?代理、跟踪更新等都有很多好处。