我有DB查看ALL_ATM_DEV_SATTRIB_VALS
DEVICE_ID ATTRIB_ID INT_VALUE STRING_VALUE DATE_VALUE
1 13 null 10.0.3.50 null
1 14 0 null null
1 15 null null null
2 13 null 10.0.3.51 null
2 14 2 null null
2 15 null null null
实体对象
public class AttributeValue: IAttributeValue
{
public virtual string StringValue { get; set; }
public virtual DateTime? DateValue { get; set; }
public virtual int? IntValue { get; set; }
}
public class Device : IDevice
{
public virtual long Id { get; set; }
public virtual IDictionary<long, IAttributeValue> Values { get; set; }
}
映射文件(hbm)
<class name="Device" table="DEVICES" lazy="true" >
<id name="Id" column="ID" ></id>
<map name="Values " batch-size="10" table="ALL_ATM_DEV_SATTRIB_VALS" lazy="true">
<key column="DEVICE_ID" />
<index column="ATTRIB_ID" type="System.Int64" />
<composite-element class="AttributeValue">
<property name="StringValue" column="STRING_VALUE" />
<property name="DateValue" column="DATE_VALUE" />
<property name="IntValue" column="INT_VALUE" />
</composite-element>
</map>
</class>
选择字典值可以正常工作,但是当我尝试在Linq表达式中使用它时
List<IDevice> a = dc.Get<IDevice>()
.Where(x=>x.Values[13].StringValue
.ToLower().Contains("10.0.3"))
.ToList();
nhibernate throw exception
System.InvalidOperationException: Cannot create element join for a collection of non-entities!
在对象Device
中,我需要IDictionary
。键是ATTRIB_ID(长),值是AttributeValue
答案 0 :(得分:0)
Nhibernate无法使用IDictionary<long, IAttributeValue>
创建sql-query,因为IAttributeValue不会在hbm中映射为实体。
但我解决了这个问题。
我将一个IDictionary
的映射替换为三个更简单:
<map name="StringValues" table="ALL_ATM_DEV_SATTRIB_VALS" lazy="true" fetch="select">
<key column="DEVICE_ID" />
<index column="ATTRIB_ID" type="System.Int64" />
<element column="STRING_VALUE" type="System.String"/>
</map>
<map name="DateValues" table="ALL_ATM_DEV_SATTRIB_VALS" lazy="true" fetch="select">
<key column="DEVICE_ID" />
<index column="ATTRIB_ID" type="System.Int64" />
<element column="DATE_VALUE" type="System.DateTime"/>
</map>
<map name="IntValues" table="ALL_ATM_DEV_SATTRIB_VALS" lazy="true" fetch="select">
<key column="DEVICE_ID" />
<index column="ATTRIB_ID" type="System.Int64" />
<element column="INT_VALUE" type="System.Int64"/>
</map>
我将此地图仅用于创建结果sql-query ,这就是为什么lazy=true
存在的原因,以及
永远不会在实体IDevice
此映射的数据一次选择了另一个sql-query,因为延迟初始化会导致数据库上出现n + 1个sql查询。
我的问题中的Linq查询转换为:
List<IDevice> a = dc.Get<IDevice>()
.Where(x=>x.StringValues[13].ToLower().Contains("10.0.3"))
.ToList();
在IDevice
实体中定义了三张地图:
public virtual IDictionary<long, long> IntValues { get; set; }
public virtual IDictionary<long, string> StringValues { get; set; }
public virtual IDictionary<long, DateTime> DateValues { get; set; }