Свободный NHibernate - сопоставление свойства столбцу в объединенной таблице - PullRequest
4 голосов
/ 04 марта 2011

У меня есть пара таблиц, например:

  • Product {Id, Name, ManufacturerId, ...}
  • Производитель {Id, Name, ...}

Я бы хотел иметь возможность включить Имя производителя в мой объект Продукт (вместо необходимости загружать всю строку «Производитель», когда мне нужно только имя). Моя ProductMap выглядит как ...

Table("Product");
Id(x => x.Id, "Id");
Map(x => x.ProductName, "ProductName");
Map(x => x.ManufacturerId, "ManufacturerId");
References(x => x.Manufacturer, "ManufacturerId");

Что мне нужно добавить, чтобы заполнить свойство ManufacturerName моего объекта Product? Я считаю, что мне нужно сделать какой-то вызов Join (), но у меня возникают проблемы с выяснением, как написать его со всеми соответствующими параметрами. Необходимо соединить текущую таблицу (Product) с таблицей Manufacturer в Product.ManufacturerId = Manufacturer.Id и захватить столбец Manufacturer.Name, заполнив свойство ManufacturerName объекта.

Ответы [ 2 ]

6 голосов
/ 04 марта 2011

Я думаю, вы могли бы использовать formula для динамического получения имени производителя. Это не элегантное решение, и лично я предпочел бы использовать отдельное представление SQL, сопоставленное с новой сущностью (например, ProductExtra и т. Д.), Где он будет запрашивать только необходимые столбцы, но в любом случае. Вот и мы:

  1. Добавьте свойство ManufacturerName в класс продукта
  2. Добавьте строку сопоставления для этого нового свойства в ваш ProductMap:

    Table("Product");
    Id(x => x.Id, "Id");
    Map(x => x.ProductName, "ProductName");
    Map(x => x.ManufacturerId, "ManufacturerId");
    Map(x => x.ManufacturerName).Formula("(select m.ManufacturerName from Manufacturer m where m.Id = ManufacturerId)");
    
    References(x => x.Manufacturer, "ManufacturerId");
    

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

1 голос
/ 04 марта 2011

NH Соединения сложны и требуют вещей, которые ваша схема может не поддерживать. Например, первичный ключ объединенной таблицы соответствует первичному ключу вашей текущей таблицы. Он работает очень похоже на отображение OneToOne, за исключением того, что NH не создаст явного ограничения на этот эффект. Поскольку в вашем отображении дело обстоит иначе (похоже на ссылку «многие-к-одному»), я сомневаюсь, что вы могли бы сделать явное объединение работающим.

Попробуйте сопоставить свойство "pass-through":

public class Product
{
   ...

   public string ManufacturerName
   {
      get{return NHibernateUtil.IsInitialized(Manufacturer) 
                    ? Manufacturer.Name : manufacturerName;}
      set{if(NHibernateUtil.IsInitialized(Manufacturer))
             Manufacturer.Name = value 
          else
             manufacturerName = value;}
   }
}

...

//In your mapping:
Map(x => x.ManufacturerName, "ManufacturerName");

Это сохранит нормализованное имя производителя в таблице Product в качестве денормализованного поля. Поле также будет существовать в таблице «Производитель». Когда вы получаете ПРОСТО Продукт, вы получаете имя из таблицы Продуктов. После того, как Изготовитель инициализируется по какой-либо другой причине (или загружается), вы получаете имя из таблицы Изготовитель, что означает, что вы можете сохранить имя записи Изготовителя в Продукте.

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