linq error Определено значение по умолчанию для хэш-набора - PullRequest
2 голосов
/ 25 января 2012

Я определил этот запрос для возврата IEnumerable<Estructura>

 (from d in db.Direccion
  where d.Activo == true
  select new Estructura()
  {
      IdEstructura = d.IdDireccion,
      Descripcion = d.Descripcion,
              IdPadre = 0,
      lstEstructurasHijos = d.Cliente.Select(C => new Estructura()
      {
          IdEstructura = C.IdCliente,
          Descripcion = C.Descripcion,
          IdPadre = C.IdDireccion,
          lstEstructurasHijos = C.Campana.Select(Ca => new Estructura()
          {
              IdEstructura = Ca.IdCampana,
              Descripcion = Ca.Descripcion,
              IdPadre = Ca.IdCliente,
              lstEstructurasHijos = Ca.Servicio.Select(S => new Estructura()
              {
                  IdEstructura = S.IdServicio,
                  Descripcion = S.Descripcion,
                  IdPadre = S.IdCampana,
                  lstEstructurasHijos = new HashSet<Estructura>()
              })
          })
      })
  } into query
  select query);

И этот класс, связанный

 public class Estructura
 {
    public Estructura()
    {
        this.lstEstructurasHijos = new HashSet<Estructura>();
    }

    public int IdEstructura { get; set; }
    public int IdPadre { get; set; }
    public string Descripcion { get; set; }
    public IEnumerable<Estructura> lstEstructurasHijos { get;set;}
 }

Выдает эту ошибку

System.NotSupportedException: Тип 'Estructura' появляется в двух структурно несовместимых инициализациях в одном запросе LINQ to Entities.Тип может быть инициализирован в двух местах одного и того же запроса, но только если в обоих местах установлены одинаковые свойства и эти свойства установлены в одном и том же порядке.

Почему я делаю неправильно?Потому что, если я удаляю экземпляр Estructura каждого элемента и позволяю анонимному типу linq работать хорошо

Обновление

Итак, я сделал несколько изменений в запросе, но янашел эту ошибку сейчас

не удалось создать 'System.Collections.Generic.IEnumerable 1`'.Разрешить только примитив ('como Int32, String y Guid') в этом контексте

Как я могу определить пустое значение по умолчанию hashset для этого Ienumerable

Ответы [ 2 ]

1 голос
/ 25 января 2012

Похоже, у Entity Framework возникли проблемы при переводе вашего запроса во что-то, что может быть выполнено в магазине (я полагаю, на сервере базы данных). EF хорош, но не совершенен в таких переводах; иногда ему нужно помочь.

Здесь я думаю, что мы можем достичь того, что вы хотите:

  • сначала получить все соответствующие данные;
  • затем построение иерархии локально

Так что-то вроде этого:

var data = 
    db.Direccion
    .Include("Cliente.Campana.Servicio")
    .Where(d => d.Activo)
    .ToList();

Include гарантирует, что все связанные дочерние объекты извлекаются в этом запросе, а не лениво по требованию. ToList заставляет запрос быть оцененным и оставляет data в виде в памяти List<Direccion>.

Тогда мы можем просто сделать

var enumerable = 
    (from d in data
     select new Estructura
     {
     // etc as your original statement

, который будет оцениваться стандартным linq-to-objects, у которого не будет проблем с построением вашей иерархии.

0 голосов
/ 09 апреля 2013

Вы можете использовать что-то вроде

var q = (from d in db.Direccion
  where d.Activo == true
  select new
  {
      IdEstructura = d.IdDireccion,
      Descripcion = d.Descripcion,
      IdPadre = 0,
      lstEstructurasHijos = d.Cliente.Select(C => new
      {
          IdEstructura = C.IdCliente,
          Descripcion = C.Descripcion,
          IdPadre = C.IdDireccion,
          lstEstructurasHijos = C.Campana.Select(Ca => new 
          {
              IdEstructura = Ca.IdCampana,
              Descripcion = Ca.Descripcion,
              IdPadre = Ca.IdCliente,
              lstEstructurasHijos = Ca.Servicio.Select(S => new
              {
                  IdEstructura = S.IdServicio,
                  Descripcion = S.Descripcion,
                  IdPadre = S.IdCampana
              })
          })
      })
  } into query
  select query).ToList();
var result = q.Select(d=>new Estructura
  {
      IdEstructura = d.IdEstructura,
      Descripcion = d.Descripcion,
      IdPadre = d.IdPadre,
      lstEstructurasHijos = d.Cliente.Select(C => new Estructura
      {
          IdEstructura = C.IdEstructura,
          Descripcion = C.Descripcion,
          IdPadre = C.IdPadre,
          lstEstructurasHijos = C.Campana.Select(Ca => new Estructura
          {
              IdEstructura = Ca.IdEstructura,
              Descripcion = Ca.Descripcion,
              IdPadre = Ca.IdPadre,
              lstEstructurasHijos = Ca.Servicio.Select(S => new Estructura
              {
                  IdEstructura = S.IdEstructura,
                  Descripcion = S.Descripcion,
                  IdPadre = S.IdPadre
              })
          })
      })
  }

Это работает для меня

Как я могу определить пустой хэш-набор по умолчанию для этого Ienumerable?

Просто удалите lstEstructurasHijos = new HashSet<Estructura>() из запроса и позвольте конструктору инициализировать пустой список

 public class Estructura
 {
    public Estructura()
    {
        //!!!
        this.lstEstructurasHijos = new HashSet<Estructura>();
    }
    //...
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...