2013-06-17 2 views
4

У меня есть следующий родительский объект, отдел, который содержит коллекцию дочерних объектов секцийNHibernate: Проектирование дочерних объектов в родительские свойства бросает исключение

public class Department 
{ 
    private Iesi.Collections.Generic.ISet<Section> _sections; 
    public Department() 
    { 
     _sections = new HashedSet<Section>(); 
    } 
    public virtual Guid Id { get; protected set; } 
    public virtual string Name { get; set; } 
    public virtual ICollection<Section> Sections 
    { 
     get { return _sections; } 
    } 
    public virtual int Version { get; set; } 
} 

public partial class Section 
{ 
    public Section() 
    { 
     _employees = new HashedSet<Employee>(); 
    } 
    public virtual Guid Id { get; protected set; } 
    public virtual string Name { get; set; } 
    public virtual Department Department { get; protected set; } 
    public virtual int Version { get; set; } 
} 

Я хотел бы преобразовать (расплющить) его к следующему DTO

public class SectionViewModel 
{ 
    public string DepartmentName { get; set; } 
    public string SectionName { get; set; } 
} 

Использование следующего кода.

SectionModel sectionModel = null; 
Section sections = null; 
var result = _session.QueryOver<Department>().Where(d => d.Company.Id == companyId) 
      .Left.JoinQueryOver(x => x.Sections,() => sections) 
      .Select(
        Projections.ProjectionList() 
         .Add(Projections.Property<Department>(d => sections.Department.Name).WithAlias(() => sectionModel.DepartmentName)) 
         .Add(Projections.Property<Department>(s => sections.Name).WithAlias(() => sectionModel.SectionName)) 
        ) 
      .TransformUsing(Transformers.AliasToBean<SectionModel>()) 
      .List<SectionModel>(); 

Однако я получаю следующее исключение: не может разрешить свойство: Department.Name из: Domain.Section

Я даже попробовал следующее выражение LINQ

 var result = (from d in _session.Query<Department>() 
         join s in _session.Query<Section>() 
          on d.Id equals s.Department.Id into ds 
         from sm in ds.DefaultIfEmpty() 
         select new SectionModel 
          { 
           DepartmentName = d.Name, 
           SectionName = sm.Name ?? null 
          }).ToList(); 

Mappings

public class DepartmentMap : ClassMapping<Department> 
{ 
    public DepartmentMap() 
    {   
     Id(x => x.Id, m => m.Generator(Generators.GuidComb)); 
     Property(x => x.Name, 
      m => 
      { 
       m.Length(100); 
       m.NotNullable(true); 
      }); 

     Set(x => x.Sections, 
        m => 
        { 
         m.Access(Accessor.Field); 
         m.Inverse(true); 
         m.BatchSize(20); 
         m.Key(k => { k.Column("DeptId"); k.NotNullable(true); }); 
         m.Table("Section"); 
         m.Cascade(Cascade.All | Cascade.DeleteOrphans); 
        }, 
        ce => ce.OneToMany()); 
    } 
} 


public class SectionMap : ClassMapping<Section> 
{ 
    public SectionMap() 
    { 
     Id(x => x.Id, m => m.Generator(Generators.GuidComb)); 
     Property(x => x.Name, 
      m => 
      { 
       m.Length(100); 
       m.NotNullable(true); 
      }); 
     ManyToOne(x => x.Department, 
       m => 
       { 
        m.Column("DeptId"); 
        m.NotNullable(true); 
       }); 
    } 
} 

Но это выбрасывает метод или операция не реализована.

Искание руководства по поводу того, что я делаю неправильно или отсутствует.

+0

Вам нужно будет явно присоединиться к разделам в отделах ... Или просто выбрать «Departments.Name». Знаете ли вы, как будет выглядеть SQL? –

+0

Ниже представлен ожидаемый SQL 'select d.Name как deptName, s.Name как SectionName из Dept d left join section s на d.id = s.deptid order by d.Name asc, s.Имя asc' – kagundajm

ответ

2

NHibernate не знает, как получить доступ к ребенку дочернего имущества через родительский объект. Полезная вещь, которую следует помнить о QueryOver, заключается в том, что она напрямую переводится в SQL. Вам не удалось написать следующий SQL:

select [Section].[Department].[Name] 

номер: Поэтому вы не можете сделать то же самое в QueryOver. Я хотел бы создать псевдоним для Department объекта при запуске, и использовать его в списке проекции:

Department department; 
Section sections;  

var result = _session.QueryOver<Department>(() => department) 
    .Where(d => d.Company.Id == companyId) 
    .Left.JoinQueryOver(x => x.Sections,() => sections) 
    .Select(
      Projections.ProjectionList() 
       .Add(Projections.Property(() => department.Name).WithAlias(() => sectionModel.DepartmentName)) 
       .Add(Projections.Property(() => sections.Name).WithAlias(() => sectionModel.SectionName)) 
      ) 
    .TransformUsing(Transformers.AliasToBean<SectionModel>()) 
    .List<SectionModel>(); 

Я заметил в своем комментарии вы хотели бы в order by положения. Дайте мне знать, если вам нужна помощь в этом, и я, возможно, придумаю это.

Надеюсь, что это поможет!

+0

Это работает. Я вижу, где я ошибся. Да, я бы хотел «заказать», но я могу справиться. Спасибо за терпение и неприятность. – kagundajm

+0

@CallMeKags: Нет проблем! Я знаю, что QueryOver может быть сложно определить иногда. –

0

Это может быть исправлено в 3.3.3. Ищите

  • Новой функцию
  • [NH-2986] - Добавлена ​​возможность включения коллекции Into проекций

Не уверен, но если это ваша проблема, а именно, но если вы не используете 3.3.3 затем обновите и проверьте его.

АОЛ ознакомьтесь JIRA

+0

Обновлено до 3.3.3, но проблема не устранена. Возможно, проблема связана со структурой запроса. – kagundajm

0

Вы пробовали запрос Linq как

from d in Departments 
from s in d.Sections 
select new SectionModel 
{ 
DepartmentName = d.Name, 
SectionName = s == null ? String.Empty : s.Name 
} 
+0

Эта броска ** Указанный метод не поддерживается ** Исключение. – kagundajm

+0

Каков конкретный запрос linq, который вы используете? как выглядят ваши сопоставления? Я запускаю такие запросы, используя NH 3.0 и выше, без проблем. – Fran

+0

Извините! Виноват. Я называл неправильный метод для 'from d in Departments'. Работает, но возвращает внутреннее соединение, пока меня интересует левое соединение, так как есть отделы без разделов. – kagundajm

Смежные вопросы