【问题标题】:Calculated Property using a Parameter with RIA Services使用带有 RIA 服务的参数的计算属性
【发布时间】:2012-03-14 08:15:51
【问题描述】:

我正在执行地址之间的距离计算。特别是用户与特定位置之间的距离。我可以构建导致数据库计算距离并按该距离对结果排序的 LINQ 查询。但是,我在实体中找不到 RETURN 距离的方法。查询的简化版本如下:

    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);


    }

本质上,我需要将上面的数学作为 Address Entity(它是 Place 的子级)上的 Distance 属性返回。我创建了以下部分类,并且该字段确实出现在 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; }

}

因此,Distance 属性和计算取决于 GetPlacesWithinRadiusOfUser 方法的参数。

有没有办法将查询中的参数获取到地址实体,这样我就可以执行相同的计算,并在到达客户端时在实体中使用它?

我当然可以创建一个客户端例程来执行此计算,但这会变得混乱,因为我必须不断地将它注入到每个需要它的 UI 中。我更愿意在实体中返回它,这样我就可以绑定到它并显示它(本质上我想要一个从 SQL 返回的计算字段)。如果它是纯 SQL,这将是微不足道的,但我不知道如何使用 RIA 服务和实体框架来做到这一点。

还有什么想法?

【问题讨论】:

  • 一个想法:使用计算结果创建 DTO,并将其用于数据传输。只是好奇:不能使用 sql server 空间类型?

标签: c# wcf silverlight entity-framework ria


【解决方案1】:

使用实体框架,我永远无法找到一种方法来实际执行此操作(我想要的方式)。但是,我找到了一个很好的解决方案。步骤如下:

  1. 通过在 ObjectContext 上发出距离计算来创建查询......然后根据返回的值过滤 Place 查询。所有这些都是在来自客户端的一次查询调用中完成的。它不会返回距离...但我以不同的方式处理。

  2. 然后我在所有相关对象上创建了扩展方法,如下所示:

    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) 之类的操作

这实际上效果更好一些,因为无论情况如何,我都可以重用相同的扩展方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    相关资源
    最近更新 更多