我通过 NHibernate 与之交互的一些数据库表包含具有以下结构的 XML 字段:
<L xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<I>
<C>
<N>Attribute1</N>
<V>a_value</V>
</C>
<C>
<N>Attribute2</N>
<V>123</V>
</C>
</I>
</L>
基本上,每个“C”标签都包含一个属性,它的名称包含在标签“N”中,它的值包含在标签“V”中。
我想要实现的是能够在我的查询中编写这种 LINQ 语法:
..
.Where(m=>m.XMLField(attribute_name, attribute_value))
..
这样我就能够获取特定表的实体,该表的 XML 字段包含名为“ attribute_name ”的属性,字符串值由“ attribute_value ”指定。
就这么简单,XML 结构总是这样,我只需要查询具有特定值的单个属性。
进行搜索时,我发现有一种特定的技术可以实现自定义 LINQ 提供程序:
- http://www.primordialcode.com/blog/post/nhibernate-3-extending-linq-provider-fix-notsupportedexception
- http://fabiomaulo.blogspot.it/2010/07/nhibernate-linq-provider-extension.html
- 我将如何更改 Linq-to-Nhibernate 为特定列生成的 SQL?
不幸的是,我无法找到一些关于如何使用 treebuilder 的结构化文档,所以,目前这就是我所拥有的:
我已经找到了正确的 HQL 来执行这样的任务:
where [some other statements] and XML_COLUMN_NAME.exist('/L/I/C[N=\"{0}\" and V=\"{1}\"]') = 1","attribute_name", "attribute_value");
我将在 LINQ 查询中调用的方法:
public static bool AttributeExists(this string xmlColumnName, string attributeName, string attributeValue)
{
throw new NotSupportedException();
}
与 HQL 的集成部分:
public class XMLAttributeGenerator : BaseHqlGeneratorForMethod
{
public XMLAttributeGenerator()
{
SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition(() => TestClass.AttributeExists(null, null, null)) };
}
public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject,
ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
{
return treeBuilder.Exists(???);
}
}
如您所见,我仍然没有弄清楚如何正确使用带有访问者对象的树构建器来复制上面表达的 HQL 语法。有人可以帮我解决这个问题,或者至少给我一些关于树生成器使用的基本文档吗?谢谢