2010-03-15 107 views
4

假設您的實體模型中有一對一的關係。代碼生成器將具有以下屬性的裝飾它:實體框架和XmlIgnoreAttribute

[global::System.Xml.Serialization.XmlIgnoreAttribute()] 
[global::System.Xml.Serialization.SoapIgnoreAttribute()] 
public RelatedObject Relationship { get {...} set {...} } 

我想與它的所有數據已通過一個XML Web服務加載的特性一起連載我的父對象。顯然,由於這些屬性,這些相關屬性不會被序列化。

因此,對於我的目的,我只是想刪除這些「不序列我」的屬性。我可以在設計器代碼中進行查找和替換,但是我在設計器中所做的任何修改都會將這些屬性重新加入。

在我的查詢中,我是.Include()並僅顯式加載子對象我需要序列化。所以我會確保在我的查詢中沒有循環。有些子屬性不是必需的,所以我不會包含()它們,所以它們不會被序列化。

否則我該如何實現我想要做的事情?從我的應用程序爲每個子對象分別進行調用?假設我正在返回數百個父對象;我必須撥打數百個不同的電話才能讓每個孩子都有機會。

我該如何永久擺脫這些屬性?

VS 2008/EF 3.5。

回答

2

這是一個鮮爲人知的事實...實體框架+ Web服務=:'(

有三(3)可以採取解決您的問題(即XML圖形序列問題......或缺乏)的方法

我將列出每種方法在至少開發時間和實施的複雜性訂單所需[「邦換降壓」]與可擴展性,可維護性和性能[「未來打樣」]

  1. 通過電線發送時,爲每個實體創建POCO類進行投影。這是最簡單(單調)的方法,但會解決你的問題。我在最後列入了一個樣本。

  2. 使用WCF中繼您的數據。實體框架和WCF就像'來自不同母親的兄弟'。他們的目的是一起工作,但分享他們的分歧。您會注意到,所有EF生成的實體對象都是固有的[DataConctract],所有字段都是[DataMember]。這使得WCF DataContract序列化器能夠非常有效地處理圖形,並且即使在反序列化之後也可以維護對象引用。 WCF DataContract序列化器也被證明比默認的XML序列化器快10%。

  3. 使用EF 4.0自追蹤實體(STE)。這仍然是非常新的,但它是可行的。在Visual Studio 2010中,您可以選擇生成專爲N層和SOA設計的自追蹤實體。關於STE的最好的事情是使用T4轉換文本模板來生成代碼。 T4生成的類很乾淨,非常可塑,給你足夠的空間來插入你的邏輯和驗證。 Here是一個STE教程的鏈接,讓你開始。

祝你好運,我希望你找到最適合你的方法。

POCO示例。

public class CustomerPOCO 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public List<SubLocationPOCO> SubLocations { get; set; } 
    // ... 

    #region Ctors 

    public CustomerPOCO() { } 

    public CustomerPOCO(Customer customer) 
    { 
     // Inits 
     if (customer.SubLocations != null) 
      SubLocations = customer.SubLocations.Select(sl => new SubLocationPOCO(sl)).ToList(); 
    } 

    #endregion 

} 


public class SubLocationPOCO 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

    #region Ctors 

    public SubLocationPOCO() { } 

    public SubLocationPOCO(SubLocation subLocation) 
    { 
     // Inits 
    } 

    #endregion 

} 

而你的[WebMethod]就是這樣的。

[WebMethod] 
public CustomerPOCO GetCustomerByID(int customerID) 
{ 
    using (var context = new CustomerContext()) 
    { 
     var customer = (from customer in context.Customers.Include("SubLocations") 
         where customer.ID == customerID 
         select new CustomerPOCO(customer)).FirstOrDefault(); 

     return customer; 
    } 
} 
+0

很好的回答三,謝謝! – 2010-03-20 11:14:31

4

只是不這樣做。就這麼簡單。

你在你的帖子上說你想要序列化你的對象的,對不對?

現在讓我們來看看,當你做這樣的事情會發生什麼......

  1. 串行器開始轉換你的對象和它的屬性
  2. 當它發現你的對象的,它開始序列化它
  3. 雖然序列化父,如果發現孩子的對象,它是序列化和可追溯到1

沒有一點鼓勵,它永遠不會出去。

所以這些屬性是有很好的理由。

+0

不 - 我正在序列化父對象,這工作正常,但它的孩子沒有被序列化。我只是在原始問題中添加了一些信息,以指示在我的查詢中,我只包含()應該序列化的那些屬性,所以我保證沒有循環。 – 2010-03-15 04:18:00

2

Paulo是對的(+1),但他沒有告訴你如何解決這個問題。由於XML序列化是一種合法用例,即使序列化實體是錯誤的方法。

項目轉化爲匿名類型,並序列化爲例如,以序列化到JSON,我做的:

var q = from e in Context.MyEntities 
     where // ... 
     select new 
     { 
      Id = e.Id, 
      Children = from c in e.Children 
         select new 
         { 
          Id = c.Id, 
          // etc. 
         }, 
      // etc. 
     }; 
return Json(q); 

這保證沒有循環引用等,它的工作原理。

+0

感謝這個克雷格。 我不能相信這是做到這一點的唯一方法。我們通過自動生成數據圖層而快速獲得EF,現在我們不得不手動創建這些用於序列化的臨時對象。我一定在這裏錯過了一些東西,但是似乎我們已經邁出了一步,然後又一步又回到了...... – 2010-03-19 03:53:23

+0

...從我以前推出我自己的數據層的最好的事情是序列化/反序列化是完全由Web服務代理類提取。我的服務只是返回正常的對象,不必擔心序列化,我的應用程序只是收到了正常的.NET對象,並且不必擔心反序列化。現在兩端都必須手動處理序列化? 這不是對EF設計的巨大監督嗎? – 2010-03-19 04:02:30

+1

該限制不適用於EF。它是無法處理循環引用的XML序列化程序,而不是EF。如果你不喜歡你所使用的限制,你可以自由地編寫/找到你自己的序列化程序。另外,使用EF並不意味着您需要返回實體類型;您可以改爲投影到POCO上。 – 2010-03-19 13:09:09