Entity Framework и XmlIgnoreAttribute - PullRequest
4 голосов
/ 15 марта 2010

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

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

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

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

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

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

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

VS 2008 / EF 3.5.

Ответы [ 3 ]

4 голосов
/ 15 марта 2010

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

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

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

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

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

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

2 голосов
/ 20 марта 2010

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

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

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

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

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

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

Пауло прав (+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);

Это гарантирует отсутствие циклических ссылок и т. Д., И это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...