实体框架和XmlIgnoreAttribute

时间:2010-03-15 02:23:50

标签: entity-framework

假设您的实体模型中有一对一的关系。代码生成器将使用以下属性对其进行修饰:

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

我想序列化我的父对象以及通过XML Web服务加载了数据的所有属性。显然,由于这些属性,这些相关属性不会被序列化。

因此,出于我的目的,我只想删除这些“不要序列化我”的属性。我可以在设计器代码中进行查找和替换,但是我在设计器中进行的任何修改都会将这些属性放回去。

在我的查询中,我是.Include()并显式加载我需要序列化的子对象。所以我会确保我的查询中没有圆形。某些子属性不是必需的,因此我不会包含它们,因此它们不会被序列化。

否则我如何实现我想做的事情?从我的应用程序为每个子对象单独调用?假设我正在返回数百个父对象;我不得不做几百个单独的电话来接收每个孩子。

如何永久摆脱这些属性?

VS 2008 / EF 3.5。

3 个答案:

答案 0 :(得分:4)

就是不要这样做。就这么简单。

您在帖子中说明您要序列化对象的,对吗?

现在让我们看看当你做这样的事情时会发生什么......

  1. 序列化程序开始转换对象及其属性
  2. 当找到对象的时,它会开始序列化
  3. 序列化父级时,如果找到它正在序列化的子对象并返回到1。
  4. 如果没有一些鼓励,它永远不会离开。

    所以那些属性是有充分理由的。

答案 1 :(得分: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);

这保证没有循环引用等,并且它可以工作。

答案 2 :(得分:2)

这是一个鲜为人知的事实...... 实体框架+网络服务=:'(

可以采用三种方法来解决您的问题(即XML图形序列化问题......或缺少它)。

我将按照开发时间和实施复杂性的顺序列出每种方法 [“Bang-For-Buck”] 与可扩展性,可维护性和性能 [“Future Proofing” ]

  1. 通过网络发送时,为每个实体创建POCO类以进行投影。这是最简单(单调)的方法,但可以解决您的问题。我最后加了一个样本。

  2. 使用WCF中继您的数据。实体框架和WCF就像“来自不同母亲的兄弟”。它们旨在协同工作,但分享他们的差异。您会注意到所有EF生成的实体对象本质上都是[DataConctract],所有字段都是[DataMember]。这使得WCF DataContract Serializer非常有效地处理图形,并且即使在反序列化之后也可以维护对象引用。事实证明,WCF DataContract Serializer比默认的XML Serializer快10%。

  3. 使用EF 4.0自我跟踪实体(STE)。这仍然很新,但它是可行的。在Visual Studio 2010中,您可以选择生成专为N层和SOA设计的自跟踪实体。关于STE的最好的事情是使用T4转换文本模板来生成代码。 T4生成的类很干净,非常具有可塑性,为您提供了充足的空间来插入逻辑和验证。 Here是STE教程的链接,可以帮助您入门。

  4. 祝您好运,我希望您找到最适合您的方法。

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