好的伙计们,我是数据服务和LINQ的新手,迫切需要一些指导。在短短几天内,我遇到了许多意想不到的障碍,现在我就陷入了困境。我希望这些只是学习新工具的典型挫折。
我有一个WCF数据服务,用于从Gps坐标的Sql Server数据库表提供数据。特别是我有一个服务操作方法,允许您指定小数精度和纬度/经度范围,以产生更一般的数据表示。
在网络浏览器中,它似乎按预期工作。但是,当我尝试从客户端应用程序调用该操作时,返回给客户端的列表与服务生成的列表不同。
我将使用我的代码片段来解释细节:
数据服务运营:
// This is my service operation that I need to call from my client app (see below).
// It should return an IEnumerable<Gps> (Gps is one of my Entity Model
// types) list of distinct GPS rounded to the number of decimal positions
// specified and within the range specified.
[WebGet]
public IEnumerable<Gps> GetGpsView(int decimalPlaces, decimal minLatitude, decimal minLongitude, decimal maxLatitude, decimal maxLongitude)
{
// I must first return a list of anonymous-type objects
// because LINQ does not seem to allow me to construct my
// Gps object within the query (one of those other issues
// I had to tip-toe around).
var list = (from g in this.CurrentDataSource.Gps
where g.Latitude >= minLatitude &&
g.Latitude <= maxLatitude &&
g.Longitude >= minLongitude &&
g.Longitude <= maxLongitude
select new
{
Id = 0,
Latitude = Math.Round(g.Latitude, decimalPlaces),
Longitude = Math.Round(g.Longitude, decimalPlaces)
}).Distinct().ToList();
// Now that I have my results, I need to convert the items in the
// list to my Gps entity object.
IEnumerable<Gps> gpsList = list.ConvertAll<Gps>(item => new Gps
{
Id = item.Id,
Latitude = item.Latitude,
Longitude = item.Longitude
});
return gpsList;
}
如果我从客户端应用程序调用上面的方法(在Visual Studio的虚拟服务器上运行它),gpsList似乎在返回客户端之前包含正确的数据。使用我的测试参数,我得到200个不同Gps对象的列表,其值被舍入到我指定的小数位。
但是,一旦结果返回到我的客户端应用程序中的调用方法,我有一个200 Gps对象的列表,但它们都是SAME值。具体而言,重复值是我预期结果集中的最后一个值。我通过在Web浏览器中调用此操作并查看结果来确认这一点。
客户端方法:
// Partial class extension of code auto-generated by service reference.
public partial class HsiSideBySideEntities
{
public List<Gps> GetGpsView(int decimalPlaces, decimal minLatitude, decimal minLongitude, decimal maxLatitude, decimal maxLongitude)
{
this.IgnoreMissingProperties = true;
// Format my relative URI string.
string uri = string.Format("/GetGpsView?decimalPlaces={0}&minLatitude={1}M&minLongitude={2}M&maxLatitude={3}M&maxLongitude={4}M", decimalPlaces, minLatitude, minLongitude, maxLatitude, maxLongitude);
// If I debug both client and service at the same time, when I step over this
// line, it does reach my data service - and as I mentioned above, on the
// service end it appears to generate the correct results.
List<Gps> gpsList = this.Execute<Gps>(new Uri(uri, UriKind.Relative)).ToList();
// However, the results are returned to the client code, my list contains
// duplicates of the last expected record.
return gpsList;
}
}
我尝试删除“Execute()”行的“ToList()”部分,但是当我尝试在调试器中查看结果集时,它会显示一个异常,其中显示“仅支持单个枚举”这个IEnumerable。“
据我所知,我的客户端代码首先是可疑的。毕竟,每个其他测试都显示我的数据服务操作正在产生所需的结果。
我是否需要做一些不同的事情来从数据服务中获取IEnumerable对象列表?
我知道有一个CreateQuery()选项,但我已经读过Execute()是这个场景更合适的路径。
答案 0 :(得分:1)
这可能是因为:
select new
{
Id = 0,
Latitude = Math.Round(g.Latitude, decimalPlaces),
Longitude = Math.Round(g.Longitude, decimalPlaces)
}
我假设Gps实体的Id属性是您的主键。在您的示例中,您将每个返回的Gps的Id设置为零。在WCF数据服务客户端库中,具有相同主键的实体由于更改跟踪原因而被视为同一实例,因此对象图的行为与在面向对象的引用跟踪环境(如.NET)中所期望的一样。
如果由于某种原因您无法为Gps实体提供唯一ID,请考虑使用Guid作为主键。