Nhibernate выполнение запроса, соответствующего двум IEnumerable

#c# #linq #nhibernate #repository-pattern #queryover

#c# #linq #nhibernate #репозиторий-шаблон #выполнение запроса

Вопрос:

у меня есть объекты этого домена:

 public class Societa : EquatableObject<Societa>
{
    public virtual int IdSocieta { get; set; }
    public virtual string NomeSocieta { get; set; }
}

public class Attivita {
    public virtual int IdAttivita { get; set; }
    public virtual IEnumerable<ProcessoEsaminato> Processi
}

public class ProcessoEsaminato {
    public virtual ProcessoSocieta ProcessoCoperto { get; set; }
    public virtual int Anno { get; set; }
}

public class ProcessoSocieta {
    public override int Id { get; set; }
    public virtual Societa SocietaDiretta { get; set; }
    public virtual Societa SocietaService { get; set; }
}

public class Processo   {
    public virtual int Id { get; set; }
    public virtual string NomeProcesso { get; set; }
    public virtual IEnumerable<ProcessoSocieta> SocietaAttivate
}
  

я хотел бы извлечь из базы данных с помощью QueryOver или LinqToNHibernate каждое Process из Attivita с помощью NomeProcesso , SocietaDiretta.NomeSocieta и SocietaService.NomeSocieta

Итак, я думаю: я должен начать с Processo и получить те, у которых в их SocietaAttivate есть тот, который находится в Processi коллекции Attivita , глядя на ProcessoCoperto свойство каждого элемента этой коллекции

я пытаюсь это:

 public IEnumerable<object> ProcessiPerAttivita (Attivita att) {     
    ProcessoSocieta ps = null;
    var elencoPS = att.Processi.Select(p => p.ProcessoCoperto).ToList<ProcessoSocieta>();

    return _session.QueryOver<Processo>()           
        .JoinAlias(processo => processo.SocietaAttivate, () => ps)
        .Where(x => x.SocietaAttivate.IsIn(elencoPS))
        .List();            
}
  

но Where(x => x.SocietaAttivate.IsIn(elencoPS)) это не то, что я хотел, поскольку ему нужен только список идентификаторов. итак, первый вопрос: как я могу это сделать?

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

Редактировать:

теперь я пытаюсь

 _session.QueryOver<Processo>()
            .JoinAlias(processo => processo.SocietaAttivate, () => ps)
            .Where(x => x.SocietaAttivate.Any(p => elencoPS.Contains(p)) != null)           
            .List();
  

но я получаю variable 'x' of type 'ProcessoSocieta' referenced from scope '', but it is not defined

Ответ №1:

Попробуйте это:

     public IEnumerable<Processo> ProcessiPerAttivita (Attivita att) {     
    ProcessoSocieta ps = null;
    var elencoPS = att.Processi.Select(p => p.ProcessoCoperto).ToList<ProcessoSocieta>();

    return _session.QueryOver<Processo>()           
        .JoinAlias(processo => processo.SocietaAttivate, () => ps)
        .WhereRestrictionOn(processo  => ps.Id).IsIn(elencoPS.Select(el => el.Id).ToList())
        .List<Processo>();            
}
  

Вы должны использовать псевдоним ‘ps’!

Редактировать: вы можете использовать

 .List<Processo>(); and return an IEnumerable<Processo>
  

Комментарии:

1. .Где(x => ps.SocietaAttivate. IsIn (elencoPS)) не компилируется, и, как я ни пытаюсь, IsIn не работает только с коллекцией объектов

2. отлично! в чем разница между WhereRestrictionOn и Where?

3. Это то же самое, вы сужаете свой запрос, чтобы результирующий набор соответствовал вашим потребностям. Хорошее чтение: tpodolak.com/blog/2014/08/18 /…