2012-03-14 10 views
0

私はアドレス間の距離計算を行っています。具体的には、ユーザーと特定の場所との距離。データベースで距離を計算し、その距離だけ結果を並べ替えるLINQクエリを作成できます。しかし、私は方法を見つけることができませんリターンそのエンティティでの距離。クエリの簡易版は、以下の通りです:RIAサービスでパラメータを使用して計算されたプロパティ

public IQueryable<Place> GetPlacesWithinRadiusOfUser(double userLongitude, double userLatitude, int miles) 
    { 

     return (from Place in this.ObjectContext.Places 
       where RadiusOfEarth * Math.Acos((double) 
        (Math.Sin((double)Place.Addresses.First().Latitude/DegreesToRadians) * Math.Sin(userLatitude/DegreesToRadians)) 
        + 
        (Math.Cos((double)Place.Addresses.First().Latitude/DegreesToRadians) * Math.Cos(userLatitude/DegreesToRadians) 
        * Math.Cos((userLongitude/DegreesToRadians) - ((double)Place.Addresses.First().Longitude/DegreesToRadians)) 
        ) 
        ) 
        <= miles 
       select Place); 


    } 

基本的に、私は(場所の子である)アドレスエンティティ距離プロパティとして返す必要が上から数学。私は以下の部分クラスを作成し、フィールドはSilverlightクライアントに表示されます。

public partial class Address 
{ 
    //The Distance field is used to return a distance if a reference point is provided in a query 
    [DataMember] 
    public Nullable<decimal> Distance { get; set; } 

} 

ので、距離プロパティと計算がGetPlacesWithinRadiusOfUserメソッドのパラメータに依存しています。

アドレスエンティティへのクエリのパラメータを取得する方法はありますか。同じ計算を実行し、クライアントに到着した時点でエンティティで使用できるようにしますか?

私は確かにこの計算を行うクライアント側のルーチンを作成することができますが、これは、それを必要とするすべてのUIに継続的に注入する必要があるので、面倒です。私はエンティティでそれを返すことを好むので、バインドして表示することができます(基本的にSQLから返される計算フィールドが必要です)。それがSQLの場合、これは簡単なことですが、私はRIA ServicesとEntity Frameworkを使ってこれをどうやって行うのかについて迷っています。

と思っていますか?

+0

考えてみましょう:計算結果を使用してDTOを作成し、データ転送でそれらを使用します。ただ興味があります:SQL Serverの空間型は使用できません。 –

答えて

0

Entity Frameworkでは、実際にこれを行う方法(私が望むやり方)を見つけることができませんでした。しかし、私はかなり良い解決策を見つけました。以下のステップは次のとおり

  1. はObjectContextを上の距離計算を発行することにより、クエリを作成....その後、返された値によって適所クエリを濾過しました。そのすべては、クライアントからの1回のクエリ呼び出しで行われます。それは距離を返さない...しかし私はそれを別の方法で処理した。

  2. 私はそのようにようのrelaventのすべてのオブジェクトに拡張メソッドを作成しました:

    その後
    public static class AddressExtensions 
    { 
    
    
    public static double CalculateDistanceTo(this Address address1, double longitude, double latitude) 
    { 
        if (address1 == null) 
        { 
         return 0; 
        } 
    
        return Global.CalculateDistance((double?)address1.Longitude, (double?)address1.Latitude, longitude, latitude); 
    
    } 
    
    public static double CalculateDistanceTo(this Address address1, Address address) 
    { 
        if (address1 == null || address == null) 
        { 
         return 0; 
        } 
    
        return Global.CalculateDistance((double?)address1.Longitude, (double?)address1.Latitude, (double?)address.Longitude, (double?)address.Latitude); 
    
    } 
    
    public static double CalculateDistanceTo(this Address address1, User user) 
    { 
        if (address1 == null) 
        { 
         return 0; 
        } 
    
        return address1.CalculateDistanceTo(user.Addresses.FirstOrDefault()); 
    
    } 
    
    public static double CalculateDistanceTo(this Address address1, Place place) 
    { 
        if (address1 == null) 
        { 
         return 0; 
        } 
    
        return address1.CalculateDistanceTo(place.Addresses.FirstOrDefault()); 
    
    } 
    } 
    
  3. 、どこでも私は、私はUser.DistanceTo(myAddressという)のような何かができる距離を取得するために必要

状況が何であっても、同じ拡張メソッドを再利用できるので、これは実際に少しうまく機能しました。

関連する問題