可以使用 linq2db 添加自定义列吗?

我使用 linq2db 和 FluentMappingBuilder 来映射我的数据库,我想知道是否可以将自定义列映射到我的类。

这是我的查询。

SELECT p.Id,p.Name,p.Price,dbo.FN_DISTANCE_HAVERSINE(a.latitude,a.longitude,48.135538400663656,11.551979373610068) AS Distance
FROM Product p 
INNER JOIN Category c ON p.IdCategory = c.Id
INNER JOIN Store s ON p.IdStore = s.Id
INNER JOIN Address a ON s.IdAddress = a.Id
WHERE active = 1
AND CanLoad = 1
ORDER BY distance ASC

我在我的产品类中添加了 Distance,并在我的映射类中设置为非列 Property(x => x.DistanceKm).IsnotColumn();

但我不知道如何使用 linq2db 进行此查询。有可能吗?

我还尝试了另一种方法,而不是使用 Sql 函数,而是使用 linq2db 完成所有操作。 并且工作正常...

IQueryable<Product> products = GetQueryable();

products = from p in products
                           select new Product
                           {
                               Id = p.Id,Name = p.Name,Price = p.Price,DistanceKm = DistanceHelper.GetDistanceWithHaversine(productFilter.Latitude,productFilter.Longitude,p.Store.Address.Latitude,p.Store.Address.Longitude)
                           };

var result = await products.ToListAsync();

但是如果我尝试通过 Products 订购 DistanceKm,我会收到一个异常:

var result = await products.OrderByDescending(p => p.DistanceKm).ToListAsync();

例外

GetDistanceWithHaversine(value(ProductRepository+<>c__DisplayClass3_0).productFilter.Latitude,value(StoreAggregator.Api.Data.Repository.ProductRepository+<>c__DisplayClass3_0).productFilter.Longitude,p.Store.Address.Longitude)' cannot be converted to SQL.
   at LinqToDB.Linq.Builder.ExpressionBuilder.ConvertToSql(IBuildContext context,Expression expression,Boolean unwrap,ColumnDescriptor columnDescriptor,Boolean isPureExpression)

这是 linq2db 的限制,还是我可以使用其中一种方法?

编辑
我的 GetDistanceWithHaversine 实现。
dbo.FN_DISTANCE_HAVERSINE 函数完全相同,但在 sql server 上。

public static double GetDistanceWithHaversine(double lat1,double lng1,double lat2,double lng2)
{
    var R = 6371; // Radius of the earth in km
    var dLat = Deg2rad(lat2 - lat1);  // deg2rad below
    var dLon = Deg2rad(lng2 - lng1);
    var a =
        Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
        Math.Cos(Deg2rad(lat1)) * Math.Cos(Deg2rad(lat2)) *
        Math.Sin(dLon / 2) * Math.Sin(dLon / 2);

    var c = 2 * Math.Atan2(Math.Sqrt(a),Math.Sqrt(1 - a));
    var d = R * c; // Distance in km
    return d;
}

private static double Deg2rad(double deg)
{
    return deg * ((Math.PI) / 180);
}
kewen163 回答:可以使用 linq2db 添加自定义列吗?

解决方案很简单。你必须告诉 linq2db 这个函数有数据库模拟。对于您的情况,它是 Sql.FunctionAttribute

[Sql.Function("dbo.FN_DISTANCE_HAVERSINE")]
public static double GetDistanceWithHaversine(double lat1,double lng1,double lat2,double lng2)
{
    var R = 6371; // Radius of the earth in km
    var dLat = Deg2rad(lat2 - lat1);  // deg2rad below
    var dLon = Deg2rad(lng2 - lng1);
    var a =
        Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
        Math.Cos(Deg2rad(lat1)) * Math.Cos(Deg2rad(lat2)) *
        Math.Sin(dLon / 2) * Math.Sin(dLon / 2);

    var c = 2 * Math.Atan2(Math.Sqrt(a),Math.Sqrt(1 - a));
    var d = R * c; // Distance in km
    return d;
}
本文链接:https://www.f2er.com/952299.html

大家都在问