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))
..
「 attribute_value」で指定された文字列値を持つ「 attribute_name 」という名前の属性が XML フィールドに含まれている特定のテーブルのエンティティを取得できるようにします。
それと同じくらい単純です。XML 構造は常にそのようなものであり、特定の値を持つ単一の属性を照会するだけで済みます。
検索を行うと、カスタム LINQ プロバイダーを実装するための特定の手法があることがわかりました。
- http://www.primordialcode.com/blog/post/nhibernate-3-extending-linq-provider-fix-notsupported例外
- http://fabiomaulo.blogspot.it/2010/07/nhibernate-linq-provider-extension.html
- Linq-to-Nhibernate が特定の列に対して生成する SQL を変更するにはどうすればよいですか?
残念ながら、ツリービルダーの使用方法に関する構造化されたドキュメントを見つけることができなかったので、現時点ではこれが私が持っているものです:
このようなタスクを実行するための正しい 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 構文を複製する方法をまだ理解していません。誰かがこれで私を助けてくれますか、少なくともツリービルダーの使用法に関するいくつかの基本的なドキュメントを教えてくれますか? ありがとう