nhibernate地图项目订单问题

时间:2012-01-21 18:26:12

标签: c# database linq nhibernate nhibernate-mapping

大家好我需要一些想法如何通过可以为空的项目的地图元素问题来修复订单。

我正在尝试排序

IQueryable<Device> q;
q = from d in q
orderby d.Attributes[1]
orderby d.Name
select d; //<-- return only devices where device_attrib_value (d.Attributes[1])
//not null

结果中的问题查询它不返回没有device_attrib_value的元素。如果向下看你可以看到sql我觉得它错了因为必须有一些连接表达式。

问题:如何更改linq表达式或映射以提供良好的属性排序?我需要为网格中的动态列进行排序和过滤

感谢任何帮助或想法!

数据库

Simple database

映射文件

< class name="Device" table="DEVICES" lazy="false">   
    <id name="Id">
      <column name="ID" />
      <generator class="native" />
    </id>    
    <property name="Name" column="NAME"/>       
    <map name="Attributes" table="DEVICE_ATTRIB_VALUES">
        <key column="DEVICE_ID"  not-null="true"/>
        <index column="ATTRIB_ID" type="System.Int64" />
        <element column="VALUE" type="System.String"/>
    </map>    
  </class>

设备实体类

public class Device
{        
    public virtual long Id { get; set; }
    public virtual string Name { get; set; }        
    public virtual IDictionary<long, string> Attributes { get; set; }        
}

由NHibernate生成的SQL

select
        device0_.ID as ID1_,
        device0_.NAME as NAME1_
    from
        DEVICES device0_,
        DEVICE_ATTRIB_VALUES attributes1_
    where
        device0_.ID=attributes1_.DEVICE_ID
        and attributes1_.ATTRIB_ID = @p0
    order by
        attributes1_.VALUE asc,
        device0_.NAME asc;

2 个答案:

答案 0 :(得分:0)

过去我遇到过这个问题而且我记得要解决这个问题,你必须在选择列表中包含属性来检索所有可以为空的项目。

答案 1 :(得分:0)

如果您可以在地图中用地图替换地图,那么我可以建议以下解决方案:

public class Attrib
{
    public virtual long Id { get; set; }
    public virtual string Value { get; set; }
}

<class name="Device" table="DEVICES" lazy="false">
...
    <bag name="Attributes" table="DEVICE_ATTRIB_VALUES">
        <key column="DEVICE_ID" not-null="true"/>
        <composite-element class="Attrib">
            <property name="Id" column="ATTRIB_ID" type="System.Int64" />
            <property name="Value" column="VALUE" type="System.String"/>
        </composite-element>
    </bag>
...
</class>

并且此LINQ队列将包括设备,即使它们没有指定的属性

session.Query<Device>().OrderBy(d => d.Attributes.Where(a => a.Id == 1).Select(a => a.Value)).ToList();

此查询生成以下SQL

select
    device0_.ID as ID0_,
    device0_.NAME as NAME0_
from
    DEVICES device0_
order by
    (select 
         attributes1_.VALUE
    from
        DEVICE_ATTRIB_VALUES attributes1_
    where
        device0_.ID=attributes1_.DEVICE_ID
        and attributes1_.ATTRIB_ID=@p0) asc;

希望这有助于您找到更优雅的解决方案。