Получение волшебных строк из QueryOver (или, может быть, Fluent NHibernate)? - PullRequest
3 голосов
/ 29 июля 2010

Одна из многих причин использовать FluentNHibernate, новый API QueryOver и новый поставщик Linq - все потому, что они исключают «магическую строку» или строки, представляющие свойства или другие вещи, которые могут быть представлены во время компиляции.

К сожалению, я использую пространственные расширения для NHibernate, которые еще не были обновлены для поддержки QueryOver или LINQ.В результате я вынужден использовать комбинацию лямбда-выражений QueryOver и строк для представления свойств и т. Д., Которые я хочу запросить.

Я хотел бы сделать следующее: я хочуспособ спросить у Fluent NHibernate (или, возможно, API-интерфейс NHibernate QueryOver), какой должна быть волшебная строка.Вот пример псевдокода:

В настоящее время я написал бы -

var x = session.QueryOver<Shuttle>().Add(SpatialRestrictions.Intersects("abc", other_object));

Что я хотел бы написать -

var x = session.QueryOver<Shuttle>().Add(SpatialRestriction.Intersects(session.GetMagicString<Shuttle>(x => x.Abc), other_object));

Isесть что-нибудь подобное?Было бы трудно написать?

РЕДАКТИРОВАТЬ: Я просто хотел отметить, что это будет применяться гораздо больше, чем пространственное - на самом деле все, что не было преобразовано в QueryOver или LINQеще может быть польза.

Ответы [ 2 ]

4 голосов
/ 02 сентября 2010

обновление

Оператор nameof в C # 6 обеспечивает поддержку времени компиляции.


Существует гораздо более простое решение - выражения.

Возьмите следующий пример:

public static class ExpressionsExtractor
{
    public static string GetMemberName<TObj, TProp>(Expression<Func<TObj, TProp>> expression)
    {
        var memberExpression = expression.Body as MemberExpression;

        if (memberExpression == null)
            return null;

        return memberExpression.Member.Name;
    }
}

И использование:

var propName = ExpressionsExtractor.GetMemberName<Person, int>(p => p.Id);

ExpressionsExtractor - всего лишь предложение, вы можете обернуть этот метод в любой класс, какой захотите, возможно, как метод расширения или, предпочтительно, нестатический класс.

Ваш пример может выглядеть примерно так:

var abcPropertyName = ExpressionsExtractor.GetMemberName<Shuttle, IGeometry>(x => x.Abc);
var x = session.QueryOver<Shuttle>().Add(SpatialRestriction.Intersects(abcPropertyName, other_object));
0 голосов
/ 30 июля 2010

Предполагая, что я понимаю ваш вопрос, вам может понадобиться вспомогательный класс для каждого существующего объекта с такими именами, как имена столбцов, имена свойств и другие полезные вещи, особенно если вы хотите использовать поиск ICriteria. http://nhforge.org/wikis/general/open-source-project-ecosystem.aspx имеет множество проектов, которые могут помочь. NhGen (http://sourceforge.net/projects/nhgen/) создает очень простые вспомогательные классы, которые могут помочь вам указать путь проектирования для того, что вам может понадобиться.

Уточнение: после комментария "Я не понимаю"

Короче говоря, я не верю, что для вас пока есть решение. Проект QueryOver не достиг желаемого уровня. Таким образом, в качестве возможного решения между тем, чтобы удалить магические строки, создайте вспомогательный класс, чтобы ваш запрос стал

var x = session.QueryOver<Shuttle>().Add(SpatialRestrictions.Intersects(ShuttleHelper.Abc, other_object));

Таким образом, ваша магическая строка находится за каким-то другим свойством (я просто выбрал .Abc, чтобы продемонстрировать, но я уверен, что у вас будет лучшее представление о том, что вы хотите), тогда если «abc» изменится (скажем, «xyz») ) вы либо меняете имя свойства с .Abc на .Xyz, а затем у вас будут ошибки сборки, чтобы показать вам, где вам нужно обновить код (так же, как если бы вы использовали лямбда-выражения), или просто измените значение свойства .Abc на «xyz» - который действительно будет работать, только если у вашего свойства будет какое-то значимое имя (например, .OtherObjectIntersectingColumn и т. д.), а не само имя этого свойства. Это имеет то преимущество, что не нужно обновлять код для исправления ошибок сборки. В этот момент ваш запрос может быть

var x = session.QueryOver<Shuttle>().Add(SpatialRestrictions.Intersects(ShuttleHelper.OtherObjectIntersectingColumn, other_object));

Я упомянул страницу экосистемы проекта с открытым исходным кодом, так как она может дать вам несколько советов о том, какие типы вспомогательных классов сделали другие люди, так что вы, так сказать, не изобретаете колесо.

...