代码之家  ›  专栏  ›  技术社区  ›  Mike Chamberlain

实体框架和XmlIgnoreAttribute

  •  4
  • Mike Chamberlain  · 技术社区  · 14 年前

    假设在实体模型中有一对一的关系。代码生成器将使用以下属性装饰它:

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

    因此,出于我的目的,我只想删除这些“don't serialize me”属性。我可以在设计器代码中进行查找和替换,但是我在设计器中所做的任何修改都会将这些属性放回设计器中。

    否则我该如何实现我想做的?从应用程序中为每个子对象分别调用?假设我返回数百个父对象;我也得打几百个电话给每个孩子。

    如何永久删除这些属性?

    与2008/EF 3.5相比。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Tri Q Tran    14 年前

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

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

    我将按所需的最少开发时间和实现复杂性的顺序列出每种方法 [“敲竹杠”] 可扩展性、可维护性和性能 [“未来证明”] .

    1. 使用WCF传递数据。实体框架和WCF就像“来自不同母亲的兄弟”。他们被设计为一起工作,但分享他们的分歧。您将注意到,所有EF生成的实体对象本质上都是[DataConctract],所有字段都是[DataMember]。这使得WCF DataContract序列化程序能够非常有效地处理图形,并且即使在反序列化之后也能维护对象引用。WCF DataContract序列化程序也被证明比默认的XML序列化程序快10%。

    2. 使用EF 4.0自跟踪实体(STE)。这仍然是非常新的,但它是可行的。在visualstudio2010中,您可以选择生成为N层和SOA设计的自跟踪实体。STE最好的地方是使用T4转换的文本模板来生成代码。T4生成的类是干净的,并且非常有延展性,给了您足够的空间来插入逻辑和验证。 Here

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

    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;
        }
    }
    
        2
  •  4
  •   Paulo Santos    14 年前

    别这么做。就这么简单。

    您在帖子中声明要序列化 起源

    现在让我们看看当你这样做的时候会发生什么。。。

    1. 序列化程序开始转换对象及其属性
    2. 你的对象,它开始序列化它
    3. 序列化父对象时,如果找到要序列化的子对象,则返回1。

    如果没有一些鼓励,它永远也出不来。

    所以这些属性存在是有充分理由的。

        3
  •  2
  •   Craig Stuntz    14 年前

    保罗是对的,但他没有告诉你如何解决这个问题。因为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);
    

    这保证了没有循环引用等,而且它是有效的。