值“CitiesDomain.Cities”可以是“CitiesDomain.Cities”。不是“CitiesDomain.Cities”类型并且不能在此通用集合中使用。参数名称:值
我需要一些帮助来解决我收到的此错误消息。基本上,我正在使用 C# .NET 和 NHibernate 开发动态报告类库。
报告本身将通过一个类来实现,使用自定义属性来指定它所需的元数据和任何参数,包括它可能需要的任何查找表,例如:
[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 { }
当 Web 应用程序启动时,它会枚举 \bin 中的所有程序集
文件夹并通过查找已用 Report
属性修饰的类来加载它们。当遇到 LookupTable
属性时,它将使用 Reflection Emit 生成一个新程序集,以创建一个具有由 IDColumn
和 ValueColumn
属性参数指定的属性的类。此外,NHibernate .hbm.xml 映射文件将动态生成并嵌入到程序集中,以便 NHibernate 本身将其加载到其配置中。
现在,当我设法走到这一步时,我却被一个不寻常的问题阻止了。我有以下代码:
Type generic = typeof( GolfScoreDAL.PersistenceManager<> );
Type constructed = generic.MakeGenericType( EntityType );
dynamic instance = Activator.CreateInstance( constructed );
dynamic results = instance.FindAll();
此代码块正在创建
PersistenceManager<CitiesDomain.Cities>
CitiesDomain.Cities
的通用 DAL 实例 通用参数取自 EntityType
属性,该属性是在程序集枚举期间设置的进程并包含域类本身的Type
。不幸的是,当调用上面的 instance.FindAll()
行时,我收到以下错误消息:
值“CitiesDomain.Cities”不是“CitiesDomain.Cities”类型,无法使用在这个通用集合中。 参数名称:值
此错误是在下面代码中的 return results.List
行上产生的:
public IList<T> FindAll()
{
using ( ISession session = OpenSession() )
{
var results = session.CreateCriteria( typeof( T ) );
return results.List<T>(); // <------ falls over here
}
}
我不明白为什么,因为泛型类型 T
与 CreateCriteria 方法返回的结果类型匹配,即在中间窗口中键入以下内容证明了这一点。
? results.List()[0] is typeof(T) true
由于某种原因,return results.List
不起作用,但 return results.List();
可以。
如果我用项目中引用的具体域类替换上面的 Type returned = generic.MakeGenericType( EntityType );
行,则它可以工作并且不会引发错误,例如 Type returned = generic.MakeGenericType( typeof(City) );
这里的模式是引用的类不会抛出异常,但动态加载的类会抛出异常。
谁能告诉我为什么代码不起作用,否则几天的工作将被扔进下水道并回到绘图板上。
提前致谢。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
EntityType 是静态类型还是运行时生成的?
Is EntityType a static type or runtime generated?