简体   繁体   English

C# 在 Linq 查询 WHERE 语句中返回两个纬度/经度坐标之间的计算距离

[英]C# Return a Calculated Distance between two Lat/Long Coordinates within a Linq Query WHERE statement

I am trying to improve performance by moving a distance calculation into LINQ to SQL instead of performing the calculation on an enumerable.我试图通过将距离计算移动到 LINQ 到 SQL 而不是对可枚举执行计算来提高性能。 Specifically, I am trying to calculate distance in miles and filter for entities within a 50 miles radius.具体来说,我正在尝试计算以英里为单位的距离并过滤 50 英里半径内的实体。

Here is my code (apologies for the lack of readability):这是我的代码(为缺乏可读性而道歉):

List<Thing> thing = _context.Things
  .AsNoTracking()
  .Where(t => (DbGeography.PointFromText(
      string.Format(
        "POINT({0} {1}",
        t.Latitude.Value, 
        t.Longitude.Value)
    ,4326)
   .Distance(
      DbGeography.PointFromText(
        string.Format(
          "POINT({0} {1}",
          other.Latitude.Value, 
          other.Longitude.Value),
      ,4326)
      * 0.000621371) <=50)
  .ToList();

Ultimately I will need to refactor this to an alternative that works in LINQ. Here is the error:最终我需要将其重构为适用于 LINQ 的替代方案。这是错误:

 System.NotSupportedException : LINQ to Entities does not recognize the method 'System.String Format(System.String, System.Object, System.Object)' method, and this method cannot be translated into a store expression.

Stack Trace: 
DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
ExpressionConverter.TranslateExpression(Expression linq)
ExpressionConverter.TranslateIntoCanonicalFunction(String functionName, Expression Expression, Expression[] linqArguments)
SpatialMethodCallTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq)
ExpressionConverter.TranslateExpression(Expression linq)
ExpressionConverter.TranslateIntoCanonicalFunction(String functionName, Expression Expression, Expression[] linqArguments)
<27 more frames...>
ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
<>c__DisplayClass7.<GetResults>b__5()
DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
IEnumerable<T>.GetEnumerator>b__0()
LazyEnumerator`1.MoveNext()
List`1.ctor(IEnumerable`1 collection)
Enumerable.ToList[TSource](IEnumerable`1 source)

I have also tried this:我也试过这个:

SqlGeography.Point(
  Convert.ToDouble(t.Latitude.Value),
  Convert.ToDouble(t.Longitude.Value),
  4326)
.STDistance(
  SqlGeography.Point(
    Convert.ToDouble(other.Latitude.Value), 
    Convert.ToDouble(other.Longitude.Value), 
    4326)) * 0.000621371) <= 50)

Same System.NotSupportedException for Linq to SQL translation. Linq 到 SQL 转换的相同 System.NotSupportedException。

I resolved this by just concatenating the strings in DbGeography.FromText() (changed from DbGeography.PointFromText()).我通过连接 DbGeography.FromText() 中的字符串(从 DbGeography.PointFromText() 更改而来)解决了这个问题。 Also did have to reverse lat long to long lat.也确实必须将经纬度反转为经纬度。

DbGeography.FromText("POINT(" + t.Longitude.Value + " " + t.Latitude.Value + ")"
,4326)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM