2010-03-15 7 views
4

Скажите, что у вас есть отношения «один к одному» в вашей модели сущности. Генератор коды украсит его со следующими атрибутами:Entity Framework и XmlIgnoreAttribute

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

Я хочу сериализации моего родительского объекта вместе со всеми его свойствами, для которых данные были загружены через XML веб-сервис. Очевидно, что эти связанные свойства не получают сериализации из-за этих атрибутов.

Так что для моих целей я просто хочу удалить эти атрибуты «не сериализуйте меня». Я могу найти и заменить код конструктора, но любые модификации, которые я делаю в дизайнере, вернут эти атрибуты.

В моем запросе я .Include() и явным образом загружаю только дочерние объекты, которые Я требую для сериализации. Поэтому я буду уверен, что в моем запросе нет круглых точек. Некоторые из дочерних свойств не требуются, поэтому я не буду включать() их, поэтому они не будут сериализованы.

Else Как достичь того, что я хочу сделать? Сделайте отдельный вызов из моего приложения для каждого дочернего объекта? Скажем, я возвращаю сотни родительских объектов; Я должен был бы сделать сотни отдельных звонков, чтобы получить каждого ребенка.

Как я могу окончательно избавиться от этих атрибутов?

VS 2008/EF 3.5.

ответ

2

Вот малоизвестный факт ...Entity Framework + Web Services =: '(

Есть три (3) подходы, которые могут быть приняты, чтобы решить вашу проблему (а именно проблему XML граф сериализации ... или его отсутствие)

.

я перечислю каждый подход по порядку наименьшего времени разработки и сложности реализации требуется [ «Bang-For-Бака»] против масштабируемости, ремонтопригодность и производительности [ «Future Правописание»].

  1. Создавайте классы POCO для каждого объекта для проецирования при отправке по проводу. Это самый простой (и однообразный) подход, но решает вашу проблему. Я включил образец в конце.

  2. Используйте WCF для передачи ваших данных. Entity Framework и WCF похожи на «братья из другой матери». Они были разработаны для совместной работы, но разделяют их различия. Вы заметите, что все объекты Entity Objects, созданные EF, по своей сути [DataConctract] со всеми полями являются [DataMember]. Это позволяет использовать WCF DataContract Serializer с графами ручек очень эффективно и поддерживает ссылку на объект даже после десериализации. WCF DataContract Serializer также оказался на 10% быстрее, чем стандартный XML-сериализатор по умолчанию.

  3. Использование EF 4.0 Self Tracking Entities (STE). Это все еще очень нова, но она работоспособна. В Visual Studio 2010 вам предоставляется возможность генерировать объекты самоконтроля, которые предназначены для N-уровня и SOA. Самое лучшее в STE - использование шаблонов T4 Transformed Text для генерации кода. Классы, созданные 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

Отличный ответ Tri, спасибо! –

4

Только не делайте этого. Это так просто.

Укажите, что вы хотите сериализовать родителя вашего объекта, не так ли?

Теперь давайте посмотрим, что происходит, когда вы делаете что-то подобное ...

  1. сериализатора начинает преобразовывать свой объект и его свойства
  2. Когда он находит родителя вашего объекта, он начинает сериализации это
  3. Хотя сериализации родителю, если найдет дочерний объект, который был сериализацию и восходит к 1.

И он никогда не выйдет, без какой-либо поддержки.

Так что эти атрибуты существуют по уважительной причине.

+0

Nope - Я сериализую родительский объект, который работает нормально, но его дети не сериализуются. Я просто добавил дополнительную информацию к исходному вопросу, чтобы указать, как в моем запросе я включаю только() в те свойства, которые должны быть сериализованы, поэтому я гарантирую, что нет круговых точек. –

2

Пауло прав (+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 в скорости от создания автоматически генерируемого слоя данных, теперь мы потеряли необходимость вручную создавать эти временные объекты для сериализации. Мне, должно быть, здесь что-то не хватает, но кажется, что мы сделали один шаг вперед, а затем один шаг назад ... –

+0

... Самое приятное, что раньше, когда я сканировал свой собственный уровень данных, состоял в том, что сериализация/десериализация полностью абстрагируется прокси-классом веб-службы. Моя служба просто вернула нормальные объекты и не беспокоилась о сериализации, и мое приложение только что получило обычные объекты .NET, и не нужно было беспокоиться о десериализации. Теперь оба конца должны заботиться о сериализации вручную? Разве это не огромный надзор над дизайном EF? –

+1

Ограничение не относится к EF. Это XML-сериализатор, который не может обрабатывать циклические ссылки, а не EF. Вы можете писать или находить свой собственный сериализатор, если вам не нравятся ограничения того, который вы используете.Кроме того, использование EF не означает, что вам необходимо возвращать типы объектов; вы можете проектироваться на POCOs. –