NHibernate中的全局查找对象引用

时间:2010-03-09 00:42:55

标签: c# nhibernate criteria

是否可以在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实例,我想发现它由id为12的ThingTwo引用。或者由它引用,也引用id为16的ThingOne。如果可能的话,第一个引用是通过SensorInput2引用的,例如。

2 个答案:

答案 0 :(得分:3)

配置映射似乎没有公开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);

现在,如果你还想获得包含这个特定IO实例的对象,你可以在一次往返中有一个很好的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();
你可以猜测,因为我们从反射开始,我们只能以反射结束。结果列表是一个数组,每个条目都是每个条件的结果,每个条件搜索可以是单个结果或结果列表。

答案 1 :(得分:0)

你的“lo”类是否包含对包含“lo”对象的对象的引用?

即。如果“Lo”被一些“Hi”对象引用:

public class Lo
{
    List<Hi> hiObjects;
}

现在,如果你有一个“Lo”的实例:

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

如果您没有这些类型的引用,可以添加它们。