3

これが、私が書いた Linq to Entities ステートメントです。

public static List<Model.User> GetNearestUsers(int userid,int count,ref Model.HangoutDBEntities context)
    {
        Model.Location myLocation=GetCurrentLocation(userid,ref context);

        return context.Locations.Where(o => EntityFunctions.DiffMinutes(DateTime.Now, o.DateTimeStamp) <= 30).OrderBy(o => Core.Location.Distance.CalculateDistance(myLocation.Latitude, myLocation.Longitude, o.Latitude, o.Longitude)).Select(o => o.User).ToList();
    }

そして、ここに CalculateDistance メソッドがあります

public static double CalculateDistance(decimal lat1,decimal lon1,decimal lat2,decimal lon2)
    {
        try
        {
            var R = 6371; // Radius of the earth in km
            var dLat = DegreeToRadian((double)(lat2 - lat1));  // Javascript functions in radians
            var dLon = DegreeToRadian((double)(lon2 - lon1));
            var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
                    Math.Cos(DegreeToRadian((double)lat1)) * Math.Cos(DegreeToRadian((double)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 (double)d;
        }
        catch
        {
            return 0.0;
        }
    }

    public static double DegreeToRadian(double angle)
    {
        return Math.PI * angle / 180.0;
    }

これに対する回避策があれば教えてください。例外が発生します

LINQ to Entities はメソッド 'Double CalculateDistance(System.Decimal, System.Decimal, System.Decimal, System.Decimal)' メソッドを認識せず、このメソッドをストア式に変換できません。

カスタム関数が Linq 2 エンティティで機能しないことは知っていますが、これに対する回避策はわかりません。助けてください。:)

4

3 に答える 3

3

データをリストにロードし、リストで計算を実行します

    var origList = context.Locations.Where(o => EntityFunctions.DiffMinutes(DateTime.Now, o.DateTimeStamp) <= 30).ToList()

 var orderedList = origList.OrderBy(o => Core.Location.Distance.CalculateDistance(myLocation.Latitude, myLocation.Longitude, o.Latitude, o.Longitude)).Select(o => o.User).ToList();

または;

context.Locations
    .Where(o => EntityFunctions.DiffMinutes(DateTime.Now, o.DateTimeStamp) <= 30).ToList()
        .OrderBy(o => Core.Location.Distance.CalculateDistance(myLocation.Latitude, myLocation.Longitude, o.Latitude, o.Longitude))
            .Select(o => o.User).ToList();

注意すべきことは、where 句の後の ToList です。

ToList() を呼び出すと、データがメモリに読み込まれ、並べ替えが Linq To Objects のタスクになります。

于 2012-08-31T14:37:03.750 に答える
0

私は最近、この問題を解決しなければなりませんでした。秘訣は、ほとんどのステートメント (Math.Pow を除く) で System.Math の代わりに System.Data.Entity.SqlServer の SqlFunctions を使用することです。

別の LINQ スタイル (from/where/let/orderby など) は便利です。これは、let キーワードを使用すると問題を分解し、読みやすくすることができるためです。

var closestLocation = await (
    from q in qryable
    where q.LAT.HasValue && q.LONG.HasValue
    // Convert derees to radians (pi / 180 = 0.01745...)
    let dbLatitudeRadians = q.LAT.Value * 0.0174532925199433
    let dbLongitudeRadians = q.LONG.Value * 0.0174532925199433
    let requestLatitudeRadians = requestLatitude * 0.0174532925199433
    let requestLongitudeRadians = requestLongitude * 0.0174532925199433
    let deltaLatitudeRadians = requestLatitudeRadians - dbLatitudeRadians
    let deltaLongitudeRadians = requestLongitudeRadians - dbLongitudeRadians
    let sinHalfLatitudeDistance = SqlFunctions.Sin(deltaLatitudeRadians / 2) ?? 0.0
    let sinHalfLongitudeDistance = SqlFunctions.Sin(deltaLongitudeRadians / 2) ?? 0.0
    let cosThisLatitude = SqlFunctions.Cos(dbLatitudeRadians) ?? 0.0
    let cosThatLatitude = SqlFunctions.Cos(requestLatitudeRadians) ?? 0.0
    let expr = Math.Pow(sinHalfLatitudeDistance, 2) + cosThisLatitude * cosThatLatitude * Math.Pow(sinHalfLongitudeDistance, 2)
    let sqrtExpr = Math.Pow(expr, 0.5)
    let sqrt1MinusExpr = Math.Pow(1 - expr, 0.5)
    let distanceInMeters = 6376500 * 2 * SqlFunctions.Atan2(sqrtExpr, sqrt1MinusExpr)
    orderby distanceInMeters
    select q
).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
于 2016-06-13T17:46:49.473 に答える
0

https://stackoverflow.com/a/5971677/292787をご覧ください

カスタム メソッドを定義して、そのメソッドを SQL に変換する方法を Entity Framework に伝えることができます。

于 2014-01-20T14:48:48.073 に答える