Mir*_*ral 6 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; }
// ...
}
Run Code Online (Sandbox Code Playgroud)
给定Io的特定实例,我想发现它由id为12的ThingTwo引用.或者由它引用并且也由具有id 16的ThingOne引用.如果可能的话,第一个引用也是通过SensorInput2引用的,例如.
好吧,配置映射似乎没有公开 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);
Run Code Online (Sandbox Code Playgroud)
现在,如果您还想获取包含此特定 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();
Run Code Online (Sandbox Code Playgroud)
正如你可以猜到的,既然我们从反思开始,我们就只能以反思结束。结果列表是一个数组,其中每个条目都是每个条件的结果,其中每个条件搜索可以是单个结果或结果列表。