QueryOver IList ‹string› свойство

У меня есть сопоставленный класс, у которого есть свойство ICollection, которое отображается как Set (с использованием сопоставлений кода). Обратите внимание, что коллекция содержит строки, а не другой сопоставленный объект. например

public class Item
{
    public virtual ICollection<string> Facts { get; set; }  
}

public class ItemMapping
{
    public ItemMapping()
    {
        Set(x => x.Facts, m =>
        {
            m.Key(k => k.Column("ItemId"));
            m.Table("Facts");
        }, col => col.Element(m =>
        {
            m.Column("Description");
            m.Type(NHibernateUtil.String);
        }));
    }
}

Это работает, и операции CRUD с элементами с фактами работают нормально.

Однако я хочу выполнить QueryOver ‹> Факты в базе данных (например, получить счетчик или первые 20 фактов или получить некоторые случайные факты), но при отсутствии объекта, как мне это сделать? Я не хочу вводить сущность Fact, потому что единственным свойством, которое она могла бы иметь, была бы строка.


person Chet    schedule 14.01.2015    source источник


Ответы (2)


Что ж, мое предложение было бы:

ввести сущность. Даже если бы у него было только одно свойство. Позже вы можете расширить это (с помощью Order, IsVisible). И если вы сделаете это везде, ваша структура будет построена только из one-to-many и many-to-one отношений между объектами первых граждан. Это означает простое «обобщение фреймворка, повторное использование ...»

Но я вижу, что вам это не нравится (пожалуйста, хотя бы попробуйте переосмыслить) - так что есть способ:

NHibernate Как выполнить запрос к свойству IList?

Где я пытался показать, что (на основе документации) мы можем использовать волшебное слово ".elements":

17.1.4.1. Ссылки на псевдонимы и свойства

Итак, запрос, который коснется строковых элементов в вашем случае

Item item = null;
string fact = null;
var demos = session.QueryOver<Item>(() => item)
       .JoinAlias(i => i.Facts, () => fact)

        // instead of this
        // .Add(Restrictions.Eq("fact", "abc"))

        // we can use the .elements keyword
        .Where(Restrictions.Eq("fact.elements", "abc"))

        .List<Item>();

Таким образом, вы можете получить элементы, которые содержат некоторые факты, равные "abc"

person Radim Köhler    schedule 15.01.2015
comment
Я принял этот ответ как, вероятно, лучший способ обойти это. Причина, по которой я не хотел сопоставлять его с сущностью, заключается в том, что, на мой взгляд, это противоречит принципам YAGNI / KISS, т.е. вы можете позже расширить его и т. Д. В итоге я сопоставил его, поскольку он дает мне дополнительную гибкость QueryOver ‹› () /опции.. - person Chet; 19.01.2015
comment
Мне не удалось воспроизвести этот ответ, даже несмотря на простейший код. Я где-то читал, что может быть ошибка с псевдонимом в старых версиях NHib (‹4?). В любом случае, мне пришлось создать класс для представления строкового элемента, и тогда я мог без проблем выполнять свои QueryOvers. Немного отстой, но, по крайней мере, у меня есть безопасность типов. - person ctrlplusb; 17.01.2016

не сущности должны быть запрошены их сущностями и затем выбраны. Например, чтобы получить первые 20 фактов:

string fact = null;
var first20facts = session.QueryOver<Item>()
    .JoinAlias(i => i.Facts, () => fact)
    .OrderBy(() => fact).Asc
    .Take(20)
    .Select(() => fact)
    .List<string>();

В качестве альтернативы вы также можете сопоставить объект, доступный только для чтения, для Fact, просто чтобы запросить его.

person Firo    schedule 15.01.2015