我最近问过一个非常类似的问题,但是虽然标题提到了课程,但我的内容主要是指一个元组,而(非常好的)答案反映了这一点。当我试图用一个类代替元组时,我得到TargetParameterCountException: Parameter count mismatch.
异常。
How can I get NHibernate to map to a Tuple or Class?
我有以下方法从数据库中获取结果列表。
public static IList<T> Find<T>(DetachedCriteria crit) where T : class
{
lock (_locker)
{
return crit.GetExecutableCriteria(InstanceSession)
.List<T>();
}
}
这通常很有效。但是,我已经更改了一个调用上述方法的方法。
public IList<FooBarResult> FindResults(FooBarTask st)
{
return DataAccess.Find<FooBarResult>(DetachedCriteria.For<FooBarResult>()
.Add(Restrictions.Eq("Task", st))).ToList();
}
哪个适用于此(因为我不想返回整个FooBarResult
,只有某些列)。
public IList<MyCustomClass> FindResults(FooBarTask st)
{
var typeConstructor = typeof(MyCustomClass).GetConstructors()[0];
return DataAccess.Find<MyCustomClass>(DetachedCriteria.For<FooBarResult>()
.Add(Restrictions.Eq("Task", st))
.SetProjection(
Projections.ProjectionList()
.Add(
Projections.Property("FieldOne") //this is a DateTime
)
.Add(
Projections.Property("FieldTwo") //this is a Guid
)
.SetResultTransformer(Transformers.AliasToBeanConstructor(typeConstructor))
)
);
}
这就是上课。
public class MyCustomClass
{
public MyCustomClass()
{
//placeholder
}
public MyCustomClass(DateTime FieldOne, Guid FieldTwo)
{
this.FieldOne = FieldOne;
this.FieldTwo = FieldTwo;
}
public DateTime FieldOne { get; set; }
public Guid FieldTwo { get; set; }
}
如前所述,在运行return crit.GetExecutableCriteria(InstanceSession).List<T>();
代码时,我得到TargetParameterCountException: Parameter count mismatch.
例外。
有什么方法可以让它返回我MyCustomClass
的列表吗?
答案 0 :(得分:2)
我没有对此进行过测试,但您应该使用Transformers.AliasToBean
查看别名以使变换器工作:
public IList<MyCustomClass> FindResults(FooBarTask st)
{
var typeConstructor = typeof(MyCustomClass).GetConstructors()[0];
return DataAccess.Find<MyCustomClass>(DetachedCriteria.For<FooBarResult>()
.Add(Restrictions.Eq("Task", st))
.SetProjection(
Projections.ProjectionList()
.Add(Projections.Property("FieldOne"), "FieldOne")
.Add(Projections.Property("FieldTwo"), "FieldTwo")
)
.SetResultTransformer(Transformers.AliasToBean(typeof(MyCustomClass)))
.List<MyCustomClass>()
}
答案 1 :(得分:1)
在这一行:
var typeConstructor = typeof(MyCustomClass).GetConstructors()[0];
你将得到第一个默认构造函数,它的签名显然不匹配。对您的案例最简单的解决方法是:
var typeConstructor = typeof(MyCustomClass).GetConstructors()[1];
但最干净的解决方案将是这些方面(未经测试,也有点简化):
var typeConstructor = GetMatchingConstructorOrThrow<MyCustomClass>
(typeof(DateTime), typeof(Guid));
// ...
private ConstructorInfo GetMatchingConstructorOrThrow<T>(params Type[] requiredSignature)
where T : class
{
foreach (var c in typeof(T).GetConstructors())
{
var currentSignature = c.GetParameters().Select(p => p.ParameterType);
if (currentSignature.SequenceEqual(requiredSignature))
{
return c;
}
}
throw new NoMatchingConstructorFoundException();
}