如何使用Criteria API在多对多关系中查询基元类型?

时间:2015-09-22 14:27:17

标签: c# sqlite nhibernate nhibernate-criteria

我有一个“书签”实体,其标签是字符串。在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>();

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

1 个答案:

答案 0 :(得分:1)

我建议遵循这些

要通过集合过滤(WHERE),我们可以使用: "MyArray.elements" 构建

.Add(Restrictions.Eq("Tags.elements", ...));

要选择SELECT,我们必须添加别名(定位colleciton),查询将如下所示:

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>();

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