在linq中使用自定义sql server功能

本文关键字:sql server 功能 自定义 linq | 更新日期: 2023-09-27 18:19:09

我在SQL Server中有一个保存所有存储信息的表。

列为:

storeId, locationLongitude, locationLatitude

和一个sql函数getDistance,它接受参数(Customer Longitude, Customer Latitude, store Longitude, store Latitude)

我当前的sql查询是:

SELECT TOP 5 
   dbo.[getDistance] (473.510432, -122.154381, locLatitude, locLongitude, 'Miles') AS distance, 
   loclatitude, loclongitude, storeId , 
FROM 
   storelocation WITH(NOLOCK)  
ORDER BY 
   distance; 

我目前正在缓存所有的存储信息,然后运行一个linq来过滤掉数据,有没有办法在linq中调用getDistance ?

在linq中使用自定义sql server功能

您可以使用这个包来扩展Linq-to-Entities (EF 6.1),以便您的上下文支持表值函数。

首先,你需要在你的上下文中添加一个方法,像这样;(将名称"MyContext"替换为您的上下文类型名称)

    [DbFunction("MyContext", "getDistance")]
    [DbFunctionDetailsAttribute(ResultColumnName = "locationId", DatabaseSchema = "dbo")]
    public IQueryable<StoreInfo> getDistance(int locLatitude, int locLongitude)
    {
        return F2<StoreInfo, int, int>("getDistance", "locLatitude", locLatitude, "locLongitude", locLongitude);
    }

调用一个你还需要添加的实用函数;

    private IQueryable<TResult> F2<TResult, TParam1, TParam2>(string functionName, string parameterName1,
        TParam1 parameterValue1, string parameterName2,
        TParam2 parameterValue2)
    {
        var queryString = string.Format("[{0}].[{1}](@{2}, @{3})", GetType().Name, functionName, parameterName1, parameterName2);
        var parameter1 = new ObjectParameter(parameterName1, parameterValue1);
        var parameter2 = new ObjectParameter(parameterName2, parameterValue2);
        var query = this.ObjectContext.CreateQuery<TResult>(queryString, parameter1, parameter2);
        return query;
    }

最后,在OnModelCreating中注册函数返回的类型;

        modelBuilder.ComplexType<StoreInfo>();

现在你的上下文有了一个IQueryable,你可以在link -to-entities中使用它