NHIbernate: ярлык для проецирования всех свойств? - PullRequest
7 голосов
/ 23 апреля 2011

Я пытаюсь сгенерировать SQL в соответствии с:

SELECT 
  t.*, 
  SELECT (...)
FROM Title t
[trimmed]

с использованием QueryOver

Title title = null;

var q = session
   .QueryOver(() => title)
   .Select(
      Projections.Alias(Projections.Property<Title>(t => t.Id), "Id"),
      Projections.Alias(Projections.Property<Title>(t => t.Name), "Name"),
      ....
      Projections.SubQuery(sq.Where(tt => tt.Id == title.Id))), "TopLevelGenre")
)
[code trimmed]

В Title есть 15 свойств, которые я хотел бы спроецировать.Есть ли более простой способ сделать это, чтобы мне не приходилось проецировать каждое свойство отдельно, как я начал делать выше?

Ответы [ 7 ]

2 голосов
/ 28 июня 2011

Я обнаружил, что в NHibernate 3.2 это невозможно без ручного перечисления всех свойств.

1 голос
/ 10 марта 2012

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

1 голос
/ 07 ноября 2011

Если вы не возражаете против ICriteria, это работает. Я проверил с 2.1.2, но я не понимаю, почему, если не будет работать с 3.x.

var projectionList = Projections.ProjectionList();
var metadata = session.SessionFactory.GetClassMetadata(typeof(Title));
foreach (var name in metadata.PropertyNames)
{
    projectionList.Add(Projections.Property(name), name);
}
var criteria = DetachedCriteria.For<Title>()
   .SetProjection(projectionList)
   ...;
0 голосов
/ 19 апреля 2018

Это возможно в NHibernate 5.1 через Проекции объектов :

Title title = null;

var q = session
   .QueryOver(() => title)
   .Select(
      Projections.Entity(() => title),
      Projections.SubQuery(sq.Where(tt => tt.Id == title.Id))), "TopLevelGenre")
)
0 голосов
/ 14 октября 2013

Я решил это с помощью этого кода. Я надеюсь, что это может служить вам. Я просто использую сумки, просто измените сравнение, если вам нужно использовать ISet, например. PDM - это сущность, свойства которой я применяю для отражения. Вы можете изменить этот метод на общий.

        ProjectionList list = Projections.ProjectionList();            
        var metadata = session.SessionFactory.GetClassMetadata(typeof(PDM));

        foreach (var name in metadata.PropertyNames)
        {
            PropertyInfo property = typeof(PDM).GetProperties(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(x => x.Name.Equals(name));
            FieldInfo field = typeof(PDM).GetFields(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(x => x.Name.Equals(name));

            if (property != null)
            {
                if (!property.PropertyType.Name.Contains("IList"))
                {
                    list.Add(Projections.Property(name), name);
                }
            }

            if (field != null)
            {
                if (!field.FieldType.Name.Contains("IList"))
                {
                    list.Add(Projections.Property(name), name);
                }
            }
        }          
0 голосов
/ 25 апреля 2011

Можно ли создать представление таблицы заголовков с интересующими вас столбцами?или, возможно, вы захотите попробовать разделить свойства класса Title по двум классам (класс TitleBase и класс Title, унаследованный от класса TitleBase).Соответственно вам нужно создать два отдельных файла сопоставления.

Предположим, если все интересующие вас свойства находятся в классе TitleBase, используйте его в вышеупомянутом запросе.

0 голосов
/ 25 апреля 2011

Если вам нужны объекты Title, вы можете просто написать:

IList<Title> list = session.QueryOver<Title>.Where(/*some condition*/).List();  

nHibernate заполнит все атрибуты Title для вас.
см. здесь для получения дополнительной информации.

...