具有父子關係時,帶有 EF Code First 的 WebApi 會生成錯誤
我正在為這個問題頭疼。我確實在網際網路上找到了一些關於它的東西,但沒有一個明確的答案。我的問題:
我必須在 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?.