Свободное отображение NHibernate класса, где Id является ссылкой на другой класс

Я пытаюсь использовать свободный nHibernate для сопоставления класса, который существует только как контейнер для других классов и не имеет собственного идентификатора. Но я хочу, чтобы идентификатор класса был другим классом. Это действительно не имеет смысла, возможно, будет проще объяснить на примере структуры данных.

abstract QueryBuilder
{
  public IEnumerable<string> Category1Keys {get; set;}
  public IEnumerable<int> Category2Ids {get; set;}
  public IEnumerable<int> Category3Ids {get; set;}
}

Set
{
  public int Id {get; set;}
  public string Name {get; set;}
  public SetQueryBuilder QueryBuilder{get; set;}
}

SetQueryBuilder : QueryBuilder
{
}

News
{
  public int Id {get; set;}
  public string Name {get; set;}
  public NewsQueryBuilder QueryBuilder{get; set;}
}

NewsQueryBuilder : QueryBuilder
{
}

Теперь QueryBuilder - это имя, это концепция, которую мы используем для сопоставления различных (не связанных) элементов с одними и теми же категориями. Итак, вещи, которые могут использовать QueryBuidler, - это новости, страницы, разрешения.

Потому что все различные элементы, которые используют QueryBuilder, отображают эту взаимосвязь таким же образом, и иногда мы фактически используем параметры из одного типа QueryBuilder в качестве критерия выбора для другого типа QueryBuilder (т.е. если новости имеют QB из A, получите все Наборы, соответствующие тем же критериям), я хочу иметь абстрактный класс QueryBuilder, а затем расширить его для всех вещей, которые имеют сопоставления со всеми категориями.

Вот пример Set DB для построителя запросов. В базе данных QueryBuilder нет фактического элемента - он состоит из всей информации из таблиц соединения классов категорий.

f_set
{
  set_id (PK, int)
  name (varchar)
}

f_set_cat1
{
  set_id (PK, FK, int)
  cat1_key (PK, FK, char(3))
}

f_set_cat2
{
  set_id (PK, FK, int)
  cat2_id (PK, FK, int)
}

f_set_cat3
{
  set_id (PK, FK, int)
  cat3_id (PK, FK, int)
}

Моя проблема заключается в том, как сопоставить каждый экземпляр класса QueryBuilder в nHibernate, поскольку он не имеет реального ключа или записи в таблице, я хотел бы сказать, что Id - это ссылка на набор, который используют все сопоставления категорий.

Вот мои беглые сопоставления:

SetMapping : ClassMap<Set>
{
  public SetMapping()
  {
    Schema("cam");
    Table("f_set");
    Id(x => x.Id, "f_set_id").GeneratedBy.Identity();
    Map(x => x.Name, "name").Not.Nullable();
    HasOne<SetQueryBuilder>(x => x.QueryBuilder);
  }
}

SetQueryBuilderMapping : ClassMap<SetQueryBuilder>
{
  public SetQueryBuilderMapping()
  {
    References(x => x.Set, "set_id");
    HasMany(x => x.Category1Keys).Table("f_set_cat1").Element("cat1_key").KeyColumn("set_id");
    HasMany(x => x.Category2Ids).Table("f_set_cat2").Element("cat2_id").KeyColumn("set_id");
    HasMany(x => x.Category2Ids).Table("f_set_cat3").Element("cat3_id").KeyColumn("set_id");
  }
}

Мы будем очень благодарны за любую помощь на последнем этапе составления карты. Спасибо, Саан.

ДАЛЬНЕЙШИЕ ИССЛЕДОВАНИЯ Хорошо, я немного исследовал это и обнаружил, что объединение двух классов будет работать нормально, если я сделаю это:

CLASS:
Set
{
  public int Id {get; set;}
  public string Name {get; set;}
  //public SetQueryBuilder QueryBuilder{get; set;}

  public IEnumerable<string> Category1Keys {get; set;}
  public IEnumerable<int> Category2Ids {get; set;}
  public IEnumerable<int> Category3Ids {get; set;}
}

MAPPING
SetMapping : ClassMap<Set>
{
  public SetMapping()
  {
    Schema("cam");
    Table("f_set");
    Id(x => x.Id, "f_set_id").GeneratedBy.Identity();
    Map(x => x.Name, "name").Not.Nullable();
    //HasOne<SetQueryBuilder>(x => x.QueryBuilder);

    HasMany(x => x.Category1Keys).Table("f_set_cat1").Element("cat1_key").KeyColumn("set_id");
    HasMany(x => x.Category2Ids).Table("f_set_cat2").Element("cat2_id").KeyColumn("set_id");
    HasMany(x => x.Category2Ids).Table("f_set_cat3").Element("cat3_id").KeyColumn("set_id");
  }
}

При выполнении сопоставлений nHibernate это имеет смысл, но мне бы очень хотелось, чтобы все сопоставления категорий были в отдельном классе SetQueryBuilder.

Еще раз спасибо за любую помощь, Саан


person Saan    schedule 04.03.2011    source источник


Ответы (1)


Вы ищете стратегию создания подклассов. Взгляните на этот http://nhibernate.info/doc/nh/en/index.html#inheritance

Вероятно, вы захотите следовать таблице для каждого класса с таблицей для стратегии подкласса imo.

person Vadim    schedule 04.03.2011
comment
Привет, Ядс. Спасибо за ответ, но я не уверен, что сопоставления подклассов применимы здесь, хотя QueryBuilder является абстрактным классом, на самом деле подкласса для его расширения нет. И у Defiantley нет базового класса в БД, который можно было бы расширить. Это просто набор объединяемых таблиц, которые концептуально связаны друг с другом. Фактическая ошибка, которую я получаю, заключается в том, что объекту GcmQueryBuilder не сопоставлен идентификатор. Используйте метод Id для сопоставления своего свойства идентификации. Например: Id (x = ›x.Id) .. Идентификатор таблицы - это идентификатор таблицы Set или News. - person Saan; 07.03.2011
comment
Может, я просто не понимаю, что ты имеешь в виду. Не могли бы вы дать мне более подробную информацию о решении, которое, по вашему мнению, будет работать. Извините, я все еще новичок в nHibernate. Спасибо, Саан - person Saan; 07.03.2011
comment
@Saan, если это действительно построитель запросов, его не следует отображать как сущность nhibernate. Ваши категории (если они действительно связаны с набором) должны быть связаны с установленным объектом. Конструктор запросов должен действительно помочь в создании запроса. Поэтому я не уверен, что ваша архитектура имеет смысл в контексте NHibernate. - person Vadim; 07.03.2011
comment
Да, мы, наконец, тоже так решили. Мы сделали QueryBuilder интерфейсом, чтобы мы могли передавать его другим объектам, которые знают о QueryBuilders, а затем детали категории затем помещаются в Set. Большое спасибо за вашу помощь. - person Saan; 08.03.2011