NHibernate 3, Dynamic-Component, Dictionaries, and LINQ Queries
Asked Answered
V

2

7

I've got this entity with a <dynamic-component> entry and a number of properties on it. It's being consumed on the entity class as an IDictionary.

The mapping works fine and everything is hunky dory until I go to query based on values in this dictionary.

First I tried the following linq query:

repository.Where(x => x.Specifications[key] == value) 

To query against it. (Specifications is the dynamic component) The query resulted in the following error:

Unhandled Exception: System.InvalidCastException: Unable to cast object of type 'NHibernate.Type.ComponentType' to type 'NHibernate.Type.CollectionType'.

Figuring this might be outside the bounds of the Linq Provider I then went on to build a BaseHqlGeneratorForMethod to handle a custom linq extension for it.

It was built up by using the treeBuilder.Dot(...) AST like this:

var specificationExpression = 
  treeBuilder.Dot( 
     visitor.Visit(arguments[0]).AsExpression(), 
     treeBuilder.Ident("Specifications")).AsExpression(); 
var targetExpression = 
  treeBuilder.Dot( 
    visitor.Visit(arguments[0]).AsExpression(), 
    treeBuilder.Ident(keyExpression.Value.ToString())).AsExpression(); 

This worked great for generating the right SQL except that the expression is cached so subsequent calls to this function would compare all the values against the first key.

From here I found the treeBuilder.DictionaryItem(...) AST Node and built the following:

var specificationExpression = 
  treeBuilder.Dot( 
     visitor.Visit(arguments[0]).AsExpression(), 
     treeBuilder.Ident("Specifications")).AsExpression(); 
var specification = 
  treeBuilder.DictionaryItem(specificationExpression, key).AsExpression(); 

Once again I was met with the following error:

Unhandled Exception: System.InvalidCastException: Unable to cast object of type 'NHibernate.Type.ComponentType' to type 'NHibernate.Type.CollectionType'.


The Question

What am I doing wrong here? Can <dynamic-component>' s not be queried on? Am I implementing this incorrectly? Could this be a bug I should report?

Mapping:

<dynamic-component name="Specifications"> 
  <property name="sp_Graphics" column="sp_Graphics" /> 
  <property name="sp_Weight" column="sp_Weight" /> 
</dynamic-component> 

Entity:

/// <summary> 
/// Specifications 
/// </summary> 
public virtual IDictionary Specifications { get; set; } 
Vullo answered 18/4, 2011 at 18:9 Comment(0)
C
4

Due to a bug in the NHibernate linq provider you will not be able to use it to query dynamic components as of 3.1.0

https://nhibernate.jira.com/browse/NH-2664

Here is hoping that a fix can be worked out for version 3.2

In the meantime you should use a Criteria or HQL query.

Charente answered 21/4, 2011 at 20:33 Comment(0)
R
4

It's fixed since NHibernate 3.3.1 (valid link here : https://nhibernate.jira.com/browse/NH-2664)

Roger answered 8/7, 2013 at 12:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.