Как вызвать хранимую функцию базы данных через Fluent Nhibernate и получить IQueryable <T>в результате - PullRequest
1 голос
/ 18 марта 2012

Я сохранил функцию базы данных для вычисленных ближайших мест:

CREATE FUNCTION LoadNearBusinesses
    (
        @latitude DECIMAL(25, 10),
        @longtitude DECIMAL(25, 10),
        @areaRadius DECIMAL(25, 10)
    )
    RETURNS TABLE
    AS
    return SELECT DISTINCT [Business].* FROM [Business] 
     LEFT JOIN [BusinessLocation] ON [BusinessLocation].Business_id = [Business].Id 
     LEFT JOIN [Location] ON [BusinessLocation].Id = [Location].Id
     WHERE 6371 * ACos(COS(@latitude* PI() / 180) * Cos([Location].Latitude * PI() / 180) * Cos(([Location].Longitude- @longtitude)* PI() / 180) + SIN(@latitude* PI() / 180) * Sin([Location].Latitude* PI() / 180)) <= @areaRadius;

А теперь мне нужно вызвать эту функцию из моего кода и получить IQueryable <<em> Business > для использования ее в сетках telerik.

Я пытаюсь:

Session.CreateSQLQuery(
                string.Format(@"SELECT * FROM [dbo].[LoadNearBusinesses]({0},{1},{2})",
                latitude, longitude, radius)).AddEntity(typeof(Business)).List<Business>();

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

У вас есть идеи? Спасибо.

Ответы [ 2 ]

0 голосов
/ 10 апреля 2012

Одна проблема, с которой вы можете столкнуться с запросом @SteveMallory (что я считаю правильным решением), заключается в том, что Linq to NHibernate не поддерживает тригонометрические функции Math, но поддерживает расширение самого себя:).

Проверьте две ссылки, чтобы решить эту проблему: http://fabiomaulo.blogspot.mx/2010/07/nhibernate-linq-provider-extension.html и https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate.Test/Linq/CustomExtensionsExample.cs

0 голосов
/ 10 апреля 2012

Это должно дать вам IQueryable<Business>, используя ту же логику, что и хранимая процедура. Для этого вам понадобится ссылка на NHibernete.Linq.

int latitude = 1;
int longitude = 2;

var q = from business in session.Query<Business>()
        join businessLocation in session.Query<BusinessLocation>()
           on business.Id equals businessLocation.Business_Id into busBusLoc
        from subBusiness in busBusLoc.DefaultIfEmpty()
        join location in session.Query<Location>()
           on businessLocation.Id equals location.Id into busBusLocLoc
        from subBusinessLocationLocation in busBusLocLoc.DefaultIfEmpty()
        where (6371 * Math.Acos(Math.Cos(latitude * Math.PI / 180) 
                    * Math.Cos(l.Latitude * Math.PI / 180) 
                    * Math.Cos((l.Longitude - longtitude) * Math.PI / 180) 
                         + Math.Sin(latitude * Math.PI / 180) 
                         * Math.Sin(location.Latitude * Math.PI / 180)))
                <= areaRadius
        select business;

Конечно, обычно ваш ORM собирается связывать сущности только через внутреннее соединение, поэтому вам нужно выполнить левые соединения вручную здесь. where и select должны быть довольно прямыми.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...