Сопоставление "многие к одному" с таблицей сбора

У меня есть простой случай с двумя сущностями Machine и Product, где Machine может иметь ноль или один Product. Обратная ассоциация (которая могла бы быть какой-то коллекцией) в коде не нужна.

Проблема заключается в устаревшей модели базы данных, и я не могу изменить структуру таблицы Machine, поэтому я создал дополнительную таблицу MachineProduct с внешними ключами для обеих таблиц. В основном то, что вы бы сделали для отношения «многие ко многим», но на практике MachineId в этой таблице будет уникальным.

Теперь мне нужно отобразить это в NHibernate. Что я могу сделать, так это сопоставить его как коллекцию «многие ко многим» и убедиться, что в коллекции Machine.Products не более одного элемента, но я чувствую, что должен быть более точный способ справиться с этим. Я предполагаю, что в этом вся суть отображения ORM.

Я использую отображение NHibernate по коду, но пример сопоставления XML также подойдет.


person Koen    schedule 07.05.2014    source источник
comment
Есть ли у существующей машины (таблица) FK to Product? Нравится Machine.ParentProductSurrogateKey? (Я бы подумал, что если бы он существует, он был бы нулевым) ....   -  person granadaCoder    schedule 07.05.2014
comment
Нет. Если бы это было так, я мог бы использовать простой метод «многие к одному». Проблема в том, что у меня нет разрешения на добавление этой связи в базу данных.   -  person Koen    schedule 07.05.2014
comment
Хорошо, теперь я понимаю лучше. Вы пытаетесь добавить несуществующую связь, но без изменения исходных таблиц. У меня нет ответа, но позвольте мне поискать то, с чем я однажды столкнулся.   -  person granadaCoder    schedule 07.05.2014


Ответы (2)


Самый простой способ, который, как я полагаю, должен делать регулярный элемент «Многие ко многим», - убедитесь, что не ссылаетесь на отношение «многие ко многим» из продукта.

<class name="Machine">
  <id ....>
  <bag name="Competencies" table="MachineProduct">
    <key column="machine_id"/>
   <many-to-many class="Product" column="product_id"/>
  </bag>
</class>

Или обычные «Один ко многим».

<set name="MachineProduct" table="MachineProduct" cascade="all-delete-orphan" inverse="true">
  <key column="machine_id"/>
  <one-to-many class="MachineProduct"/>
</set>
person Najera    schedule 07.05.2014
comment
Первое решение похоже на то, что у меня есть сейчас, но я чувствую, что должен быть какой-то лучший способ, поскольку на самом деле мне не нужна коллекция. Но, как сказано в вопросе, я могу добавить код, который управляет использованием коллекции, и публично раскрыть ее как обычную ассоциацию. - person Koen; 08.05.2014
comment
Я не уверен, что вам нужно ... как насчет отношений один на один? - person Najera; 08.05.2014
comment
По логике, это многие к одному. Обычно это можно сделать с помощью только внешнего ключа в базе данных, но, поскольку нам не разрешено изменять схему, содержащую таблицу Machine, я использую таблицу соединений (как и в случае отношений «многие ко многим»). Я ищу механизм NHibernate, который позволяет отображать многие-к-одному через таблицу соединений ... - person Koen; 09.05.2014

Вот мое обоснованное предположение.

Как вы предполагаете, при обычных обстоятельствах M: N MachineProduct будет «таблицей ссылок», и повторения могут быть возможны.

Я думаю, вы можете "выделить" отношения ... используйте ".Unique ()".

Я думаю, это лает правильное дерево.

public class MachineProductMap : ClassMap<MachineProductNHEntity>
{
    public MachineProductMap()
    {
        Schema("dbo");
        Table("MachineProduct");

        /* Your surrogate key setup here */
        Id(x => x.MachineProductUUID).GeneratedBy.GuidComb().Index("IX_MachineProduct_MachineProductUUID");

        References<MachineNHEntity>(x => x.ParentMachine)
            .Class(typeof(MachineNHEntity))
            .Not.Nullable()
             .Unique()
            .Column("ParentMachineUUID")
            .Index("IX_MachineProduct_ParentMachineUUID")
            .Cascade.SaveUpdate()
            ;
        ;


       References<ProductNHEntity>(x => x.ParentProduct)
            .Class(typeof(ProductNHEntity))
             .Nullable()
             .Unique()
            .Column("ParentProductUUID")
            .Index("IX_MachineProduct_ParentProductUUID")
            .Cascade.SaveUpdate()
            ;
        ;
    }
}

ПРИЛОЖЕНИЕ:

Я думаю, что вышеперечисленное работает, но позже вы заявите, что вам не нужен посредник.

Итак, вот еще одна попытка использовать "Присоединиться" .....

Я думаю, вам нужно что-то вроде этого:

public class Product
{
    public virtual int ProductSurrogateKey { get; set; } /* ID */
}   

public partial class Machine
    {
        public virtual Guid? MachineUUID { get; set; }
        public virtual Product TheProduct { get; set; }
    }

public class MachineMap : ClassMap<Machine>
{
    public MachineMap()
    {

        Table("Machine");

        Id(x => x.MachineUUID).GeneratedBy.GuidComb().Index("IX_Machine_MachineUUID");

        Join("MachineProductArtificialReferenceMaker", join =>
        {
            join.KeyColumn("ParentMachineUUID");
            join.References(prop => prop.TheProduct);
        });

    }
}

Будет создана таблица с названием «MachineProductArtificialReferenceMaker».

Эта таблица имеет FK для Machine.MachineUUID. (не ноль)

И FK для Product.ProductSurrogateKey (допускает значение NULL)

person granadaCoder    schedule 07.05.2014
comment
Я не это имел в виду. Сопоставление таблицы соединения с сущностью кажется излишним, поскольку оно не добавляет никакого другого значения. - person Koen; 08.05.2014
comment
Я добавил второй ответ. Это где-то есть, но я думаю, что это работает. - person granadaCoder; 13.05.2014
comment
Спасибо, но это работает только частично. Он правильно создаст и обновит запись MachineProduct, но не удалит эту запись, когда я установлю для Machine.Product значение null. Концепция NHibernate Join явно не предназначена для моего варианта использования. - person Koen; 13.05.2014
comment
Это все, что у меня есть, чувак. Удачи. Если бы у меня были варианты, я бы просто жил с хорошей строкой в ​​новой таблице. - person granadaCoder; 13.05.2014