Asp.net-Mvc-3

具有父子關係時,帶有 EF Code First 的 WebApi 會生成錯誤

  • January 11, 2018

我正在為這個問題頭疼。我確實在網際網路上找到了一些關於它的東西,但沒有一個明確的答案。我的問題:

我必須在 MVC3 Web 應用程序的模型部分上課:ParentClass 和 ChildClass 在 ParentClass 上有一個 List 類型的屬性 Children

我使用了 EF Code First,它在數據庫中巧妙地為我生成了一個父表和一個子表。

現在我需要一個返回列表或單個父類的 REST 服務。

當我從 ParentClass 中刪除屬性 Children 時,沒有問題。但是對於那裡的propoerty 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;

   }

呼叫此服務時我不會得到結果。我究竟做錯了什麼?

我必須在上下文配置中禁用代理創建:

[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; 
     }
}

這對我來說很好。

它似乎正在為您的 POCO 序列化代理類,我的第一個建議是使用 proxydatacontractresolver:http: //msdn.microsoft.com/en-us/library/system.data.objects.proxydatacontractresolver.aspx

此外,我會努力在載入數據以通過 Web 服務發送時明確說明內容……即

將父類更改為

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

}

更改您的內容以關閉延遲載入: 在 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 選擇,請參閱:什麼是 SELECT N+1?.

引用自:https://stackoverflow.com/questions/8173524