Глобальные ссылки на объекты в NHibernate - PullRequest
5 голосов
/ 09 марта 2010

Можно ли выполнить глобальное обратное нахождение объектов, управляемых NHibernate?

В частности, у меня есть постоянный класс, который называется "Io". В нескольких таблицах имеется огромное количество полей, которые могут содержать объекты этого типа. Есть ли способ (учитывая конкретный экземпляр объекта Io), чтобы получить список объектов (любого типа), которые действительно ссылаются на этот конкретный объект? (Бонусные баллы, если он может определить, какие конкретные поля действительно содержат ссылку, но это не критично.)

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

Представьте себе такую ​​структуру:

class Io
{
  public int Id { get; set; }
  // other fields specific to the Io type
}

class ThingOne
{
  public int Id { get; set; }
  public Io SensorInput { get; set; }
  public Io SolenoidOutput { get; set; }
  // other stuff
}

class ThingTwo
{
  public int Id { get; set; }
  public Io SensorInput1 { get; set; }
  public Io SensorInput2 { get; set; }
  public SubThing Doohickey { get; set; }
  // ...
}

class SubThing
{
  public int Id { get; set; }
  public Io ControlOutput1 { get; set; }
  // ...
}

Учитывая конкретный экземпляр Io, я хочу обнаружить, что на него ссылается ThingTwo с идентификатором 12. Или что на него ссылается также ThingOne с идентификатором 16. Если возможно, также, что первая ссылка - через SensorInput2 Например.

Ответы [ 2 ]

3 голосов
/ 15 марта 2010

Что ж, сопоставления конфигурации, по-видимому, не раскрывают отношения FK, так что пока какое-то отражение может найти, какой объект типов ссылается на это. Обратите внимание, что в приведенном ниже коде предполагается, что у вас есть все сопоставленные с nhibernate классы для одной сборки, а также используется C # 3.0 и выше для поддержки LINQ.

IO toSearch = nhSession.Get<IO>(5);
var assembly = Assembly.Load("EntityAssembly");
IList<Type> assemblyTypes = assembly.GetTypes();
var searchType = toSearch.GetType();
var typesThatContainedSearchTypeProperty =
    assemblyTypes.Where(
    ast => ast.GetProperties().Count() > 0 &&
    ast.GetProperties().Where(
        astp => astp.PropertyType != null && astp.PropertyType == searchType).Count() > 0);

Теперь, если вы также хотите получить объекты, которые содержат этот конкретный экземпляр ввода-вывода, у вас может быть хороший MultiCriteria, чтобы сделать это за один раз.

var multiCrit = nhSession.CreateMultiCriteria();

foreach (var type in typesThatContainedSearchTypeProperty)
{
    //maybe this class has multiple properties of the same Type
    foreach (PropertyInfo pi in type.GetProperties().Where(astp => astp.PropertyType == toSearch.GetType()))
        multiCrit.Add(nhSession.CreateCriteria(type).Add(Restrictions.Eq(pi.Name, toSearch)));
}
IList results = multiCrit.List();

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

0 голосов
/ 09 марта 2010

Разве ваш класс "lo" не содержит ссылку на объект (ы), которые содержат объект (ы) "lo"?

, т.е. если "Lo" является ссылкой на некоторое число "Hi""objects:

public class Lo
{
    List<Hi> hiObjects;
}

Теперь, если у вас есть экземпляр" Lo ":

Lo lo = new Lo();
List<Hi> hiObjects = lo.hiObjects;

Если у вас нет ссылок такого типа, вы можете добавить их.

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