我有以下代码来执行一个简单的select语句。 鉴于“SQL Not Available”错误,此查询失败。 与模式相同的代码在大约20种不同的模型中工作得很好。 实际上,如果我改变在SQL中实现的视图的设计来隐藏LoadID列,则查询失败,指出“可以执行......因为LoadID不存在。
我的问题是当这段代码,hbm.xml模型和视图设计全部对齐时,ses.Query()失败,说明“SQL不可用”
var rows = ses.Query<vInventory>().Where(c => c.CustomerRecid == recid).Select(c => new vInventory()
{
InventoryRecid = c.InventoryRecid
, ItemID = c.ItemID
, LoadID = c.LoadID
, CustomerRecid = c.CustomerRecid
}).ToList();
这是映射。
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" assembly="Asmbly" namespace="Asmbly.Models">
<class name ="vInventory" table="dbo.vInventory" dynamic-update="true">
<cache usage="read-only"/>
<id name="InventoryRecid" column="InventoryRecid" type="Int64">
<generator class="native" />
</id>
<property name="ItemID" />
<property name="LoadID" />
<property name="CustomerRecid" />
</class>
</hibernate-mapping>
更新。我获取了SQL视图的输出并将其转储到表中。 然后修改hbm.xlm以指向表。 现在ses.Query()工作正常。这不是一个可行的可能性。
请评论InventoryRecid。在SQL视图中,此属性为
ROW_NUMBER() over (...)
如何让nHibernate使用此视图并使用InventoryRecid属性? 我永远不会尝试更新此实体。
更新#2: 我从
更改了hbm.xlm映射<class name ="vInventory" table="dbo.vInventory" dynamic-update="true">
到
<class name ="vInventory" table="dbo.vInventory" dynamic-update="false">
重新编译,我的问题消失了。
不幸的是,我将其更改回true并重新编译,我的问题也没有回来。
答案 0 :(得分:2)
您是否有特殊原因要在DataTemplate
方法中创建vInventory
的新实例? nHibernate应该已经根据你的映射返回了这种类型的对象。我认为它可能搞砸了linq提供程序,因为构造函数调用无法转换为SQL。 linq提供程序将处理Select语句,就好像它是正常的Select
。
现在发生的事情是:
nHibernate获取一个查询,其中只有:IEnumerable
需要执行。所以nHibernates只查询对象的ID(因为就nHibernate而言,它不再需要任何属性)。
哪个会给你.Where(c => c.CustomerRecid == recid)
等等。
一旦你的1, 2, 3, 4, 5, ...
被执行(不在数据库上),nHibernate就会发现它需要剩下的属性,所以它会逐个查询它们的ID(不是很有效,结果很多)。现在,使用Select
作为ID wchich可能很危险,因为它只考虑当前的结果集。查询单个记录时,ROW_NUMBER
将始终为1,因此nHibernate无法再找到其余对象。