代码之家  ›  专栏  ›  技术社区  ›  Miral

nHibernate中的全局查找对象引用

  •  5
  • Miral  · 技术社区  · 16 年前

    是否可以对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的那个东西引用。例如,如果可能,第一个参考是通过传感器输入2。

    2 回复  |  直到 15 年前
        1
  •  3
  •   Jaguar    16 年前

    配置映射似乎并没有公开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实例的对象,您可以使用一个很好的多标准在一次往返中完成它。

    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();
    

    你可以猜到,既然我们从反思开始,我们只能以反思结束。结果列表是一个数组,其中每个条目都是每个条件的结果,其中每个条件搜索可能是单个结果或结果列表。

        2
  •  0
  •   Kevin Crowell    16 年前

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

    也就是说,如果“lo”被一些“hi”对象引用:

    public class Lo
    {
        List<Hi> hiObjects;
    }
    

    现在,如果您有一个“lo”的实例:

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

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