开发者

The value "CitiesDomain.Cities" is not of type "CitiesDomain.Cities" and cannot be used in this generic collection. Parameter name: value

开发者 https://www.devze.com 2023-03-27 20:09 出处:网络
I need some assistance with this error message that I am getting.Basically, I am developing a dynamic reporting class library using C# .NET and NHibernate.

I need some assistance with this error message that I am getting. Basically, I am developing a dynamic reporting class library using C# .NET and NHibernate.

The report itself will be implemented via a class using custom attributes to specify the metadata and any parameters it requires, including any lookup tables it may need, example:

[Report( Guid="{D9DEB982-02A3-4700-868D-404E615F1DDA}", 
 Title="Golf Course Report", 
 Description= "Produces a list of golf courses by city" )]
[LookupParameter( ParamName="City", LookupTable="Cities", LabelName="Select a city" )]
[LookupTable( Table="Cities", IDColumn="CityID", ValueColumn="CityName" )]
public class GolfCourseReportByCity : Report { }

When the web app starts up it enumerates through all assemblies within the \bin folder and loads them on by one looking for classes that have been decorated with the Report attribute. When it encounters a LookupTable attribute it will generate a new assembly using Reflection Emit to create a class with properties specified by the IDColumn and ValueColumn attribute parameters. Additionally, an NHibernate .hbm.xml mapping file will be generated dynamically and embedded within the assembly so that NHibernate itself will load it into its configuration.

Now, as I have managed to get this far I am being stopped in my tracks by an unusual problem. I have got the following code:

Type generic = typeof( GolfScoreDAL.PersistenceManager<> );
Type constructed = generic.MakeGenericType( EntityType );
dynamic instance = Activator.CreateInstance( constructed );
dynamic results = instance.FindAll();

This code block is creating generic DAL instance of

PersistenceManager<CitiesDomain.Cities>

The CitiesDomain.Cities generic parameter is taken from the EntityType property, which is set during the assembly enumeration process and contains the Type of the domain class itself. Unfortunately, when calling the instance.FindAll() line above I am getting the following error message:

The value "CitiesDomain.Cities" is not 开发者_运维技巧of type "CitiesDomain.Cities" and cannot be used in this generic collection. Parameter name: value

This error is being produced on the return results.List<T>(); line in the code below:

    public IList<T> FindAll()
    {
        using ( ISession session = OpenSession() )
        {
            var results = session.CreateCriteria( typeof( T ) );
            return results.List<T>(); // <------ falls over here
        }
    }

I don't understand why because the generic type T matches with the type of the results being returned by the CreateCriteria method, i.e. typing the following in the intermediate window proves this.

? results.List()[0] is typeof(T)
true

For some reason return results.List<T>(); doesn't work, but return results.List(); does.

If I replaced the Type constructed = generic.MakeGenericType( EntityType ); line above with a concrete domain class that is being referenced within the project it works and does not throw an error, e.g. Type constructed = generic.MakeGenericType( typeof(City) );

The pattern here is a referenced class does not throw an exception, but a dynamically loaded class does.

Can anyone please tell me why the code doesn't work otherwise days of work will be chucked down the drain and back to the drawing board.

Thanks in advance.


Is EntityType a static type or runtime generated?

0

精彩评论

暂无评论...
验证码 换一张
取 消