如何使用Criteria API查询多对多关系中的基本类型

本文关键字:类型 关系 何使用 Criteria API 查询 | 更新日期: 2023-09-27 18:13:53

我有一个"书签"实体,它的标签是字符串。在c#中,书签Poco类似于:

public class BookmarkEntity
{
    public virtual Guid Id { get; set; }
    public virtual ISet<string> Tags { get; set; }
}

我已经用这个重写自动映射了实体:

public class BookmarkEntityMappingOverride : IAutoMappingOverride<BookmarkEntity>
{
    public void Override(AutoMapping<BookmarkEntity> mapping)
    {
        mapping.HasManyToMany(x => x.Tags).AsSet().Element("Value").Not.LazyLoad();
    }
}

生成以下两个表:

create table "BookmarkEntity" (
    Id UNIQUEIDENTIFIER not null,
    primary key (Id)
)
create table Tags (
    BookmarkEntity_id UNIQUEIDENTIFIER not null,
    Value TEXT,
    constraint FK9061CD2928F7F2F9 foreign key (BookmarkEntity_id)
                                  references "BookmarkEntity"
)

现在,我希望能够从sqlite支持的数据库中获得唯一的标记集。目前我正在执行这个查询:

SELECT DISTINCT Value FROM Tags ORDER BY Value

这做了我想要的,但我想使用Criteria API让它更强类型。我从这样的努力开始:

Session.CreateCriteria<BookmarkEntity>()
       .SetProjection(
            Projections.Distinct(Projections.Property<BookmarkEntity>(b => b.Tags)))
       .AddOrder(Order.Asc(Projections.Property("Value")))
       .List<string>();

但是这不起作用,因为它试图查询Bookmarks表。我需要做些什么才能使其类似于我的硬编码SQL查询?

如何使用Criteria API查询多对多关系中的基本类型

我建议遵循这些

  • NHibernate: Select item with entry in element bag
  • 我如何查询一个列表属性?
要通过集合过滤(WHERE),我们可以使用:construct with "MyArray.elements"
.Add(Restrictions.Eq("Tags.elements", ...));

对于SELECT,我们必须添加别名(目标集合),查询将是这样的:

Session.CreateCriteria<BookmarkEntity>()
       .CreateAlias("Tags", "t")
       .SetProjection(
         // Projections.Distinct(Projections.Property<BookmarkEntity>(b => b.Tags))
         Projections.Distinct(Projections.Property("t.elements"))
       )
       .AddOrder(Order.Asc(Projections.Property("t.elements")))
       .List<string>();

另外,我建议在值类型集合(IList<string>)的情况下只使用HasMany