我正在使用带有NHibernate的Dynamic LINQ。 简单的例子说明了我的问题:
var q = sess.Query<User>().Select("new (Id, Login, Person.Id as PersonId)");
当User.Person == null的数据库中的用户在哪里时,抛出NullReferenceException。
这解决了这个问题:
var q = sess.Query<User>().Select(new { Id, Login, PersonId = (long?)Person.Id });
但我需要类似
的内容var q = sess.Query<User>().Select("new (Id, Login, (long?)Person.Id as PersonId)");
因为select表达式是动态生成的。 不幸的是,动态LINQ不理解转换为(long?):(
我该怎么办? 提前谢谢!
====编辑====
好的,我理解了两件事: 1.动态LINQ不知道长,只有Int64。 2.演员不是'(Int64)'而是'Int64(某事物)'。 所以我的整个代码应该是
sess.Query<User>().Select("new (Id, Login, Int64?(Person.Id) as PersonId)");
但它仍然无法解决我的整个问题,因为NHibernate现在失败了,无法执行查询[SQL:SQL not available]异常和NullReference内部异常。
答案 0 :(得分:2)
最后我掌握了这个问题。我研究了Dynamic.cs,发现Dynamic LINQ的语法非常具体。特别是字符串表达式“SomeType(SomeExpression)”仅在SomeType没有带有一个参数的构造函数时生成强制转换表达式。在其他情况下,它会生成“new SomeType(SomeExpression)”。我认为这是一个错误,并略微修改了Dynamic.cs。
现在在我的例子中,演员阵容可以制作为'Int64? Person.Id”。它不是一个“正常”的演员语法,但它对我来说就像一个魅力。动态ExpressionParser相当不错,但遗憾的是它不适合C#cast语法。
我还在Dynamic.cs中注册了类型为“long”,“int”等的短名称。
可在此处下载修改后的来源:http://1drv.ms/1cRJtSP。