nhibernate地图项目顺序问题

发布于 2024-12-28 06:39:14 字数 1675 浏览 0 评论 0原文

大家好,我需要一些想法如何解决可空项目的按地图元素排序问题。

我正在尝试排序

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 表达式或映射以提供良好的属性排序? 我需要它来对网格中的动态列进行排序和过滤

感谢任何帮助或想法!

数据库

简单数据库

映射文件

< 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>

设备实体类Sql

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

NHibernate生成的

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;

Hi all i need some ideas how to fix order by map element issue with nullable items.

I am trying to do sorting

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

The problem in result query its not return elements without device_attrib_value.If look down you can see sql i think it wrong becouse there must be some join expression.

The question: How can i change linq expression or mapping to provide good attribute sorting? I need it for dynamic columns in my grid with sorting and filtering

Appreciate for any help or ideas!

Database

Simple database

Mapping file

< 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>

Device entity class

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

Sql generated by NHibernate

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

箜明 2025-01-04 06:39:14

如果您可以在映射中将 map 替换为 bag,那么我可以建议以下解决方案:

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;

希望这可以帮助您找到更优雅的解决方案。

If you can replace map with bag in your mapping then I can suggest the following solution:

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>

and this LINQ querty will include devices even if they don't have the specified attribute

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

this query produces following 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;

Hope this help you to find more elegant solution.

写下不归期 2025-01-04 06:39:14

过去我遇到过这个问题,我记得要解决这个问题,您必须在选择列表中包含属性以检索所有项目(无论是否可为空)。

In the past I had this problem and I remember to solve this issue you must include Attributes in select list to retrieve all items whether nullable or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文