2015-06-28 4 views
4

Имея таблицу с именем ChildTable с 2-мя колоннами SourceTable и SourceId и некоторых других таблиц ParentTable1, ParentTable2 и т.д.Как скопировать ссылку таблицы переменных NHibernate?

Идентификатор найденными в SourceId может быть использован для соединения к родительской таблице, когда SourceTable имеет значение, связанное с этим таблица (1 ->ParentTable1, 2 ->ParentTable2). Например, чтобы получить все ChildTable строк, которые связаны со строками в ParentTable1 это будет достигнуто с этим запросом:

select * 
from ChildTable ct 
join ParentTable1 pt1 
    on ct.SourceTable = 1 and ct.SourceId = pt1.Id 

Я хотел бы, чтобы сопоставить эти 2 ChildTable столбцов 1 собственности на родительскую таблицу: Parent1, Parent2 ... так что один из них будет не нулевым, а остальная часть родительских свойств будет нулевым:

public class ChildClass 
{ 
    public Parent1Class Parent1 { get; set; } 
    public Parent2Class Parent2 { get; set; } 
    public Parent3Class Parent3 { get; set; } 
    . 
    . 
    . 
} 

Вопрос: как написать отображение для этого случая (отображение с помощью кода, если это возможно)?

Примечание: это для сопоставления существующих таблиц, реорганизация схемы таблиц еще не является решением (но предложения приветствуются).

Update

Для запрашивая его, кажется, достаточно, чтобы отобразить свойство ChildClass Parent1 с:

ManyToOne(property => property.Parent1, map => map.Formula("(select pt1.Id from dbo.ParentTable1 pt1 where SourceTable = 1 and pt1.Id = SourceId)")); 

и сбор детей из Parent1Class с:

mapper.Where("SourceTable = 1"); 

Для обновления/вставки, вероятно, можно воспользоваться с помощью аксессуаров, позже опубликует обновление.

+1

В ваших желаемых ChildClass являются все свойства типа Parent1Class, или они являются Parent1/2/3Class? –

+0

А, спасибо, что заметили, это была опечатка, они разные. –

+0

У вас есть условие, в котором вы хотите отфильтровать сопоставление «много-к-одному» с предложением where - на основе SourceId. Можете ли вы подтвердить, что SourceIds исправлены? Казалось бы, для этого существует неразрешенная [jira] (https://nhibernate.jira.com/browse/NH-2874). –

ответ

2

Почему бы вам не использовать Any?

Класс:

public class ChildClass 
{ 
    public virtual ParentBase Parent { get; set; } 

    // beware of proxies when casting... this may not work like this 
    public Parent1Class Parent1 { get { return Parent as Parent1Class; } } 
    public Parent2Class Parent2 { get { return Parent as Parent2Class; } } 
    . 
    . 
    . 
} 

Mapping:

Any(x => x.Parent, typeof(int), m => 
{ 
    m.IdType<int>(); 
    m.MetaType<int>(); 

    m.MetaValue(1, typeof(Parent1)); 
    m.MetaValue(2, typeof(Parent2)); 

    m.Columns(
     id => id.Name("SourceId"), 
     classRef => classRef.Name("SourceTable")); 
}); 

Существует также many-to-any, который отображает коллекцию любых типов в таблицу соотношения.

При его использовании в запросе, вы можете проверить .class или использовать подзапрос:

HQL:

select * 
from ChildTable ct join Parent 
where pt1.class = Parent1 

или

select * 
from ChildTable ct 
Where ct.Parent in (from Parant2 p where p.Property = 'Hugo') 
+0

Спасибо. Обновление родительского свойства и запрос с помощью LINQ с использованием 'child.Parent - это Parent1Class'. Невозможно получить '.Fetch (_ => _.Parent)', чтобы работать, как он бросает * Исключение типа «System.InvalidCastException» произошло в NHibernate.dll, но не было обработано в коде пользователя. Дополнительная информация: Невозможно наложить объект типа «NHibernate.Type.AnyType» на тип «NHibernate.Type.ComponentType». * То же самое для проецирования с помощью. .Select (...) '. Вероятно, выведет еще один вопрос. –

+0

Та же проблема, что и при попытке использовать литье /, чтобы иметь возможность создавать условия для родителя в предложении LINQ Where. –

+0

Попробуйте подзапросы. –