Entity Framework 平均分组
Entity Framework average with grouping
正在尝试为以下列添加平均值:经度和纬度
这是我的 SQL 查询:
SELECT
ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS ID,
r.StateProvinceRegion,
AVG(s.Longitude) AS Longitude,
AVG(s.Latitude) AS Latitude
FROM
RestaurantAddress r
INNER JOIN
Restaurant s ON s.RestaurantId = r.RestaurantId
GROUP BY
StateProvinceRegion
Entity Framework代码:
public VersionResponse GetRegions()
{
var regionList = from restaurantAddress in _context.RestaurantAddress
join restaurant in _context.Restaurant on restaurantAddress.RestaurantId equals restaurant.RestaurantId
select new { restaurantAddress.StateProvinceRegion,
restaurant.Longitude, restaurant.Latitude,
average = (new double?[] { restaurant.Longitude, restaurant.Latitude }).Average()
};
return new VersionResponse()
{
Data = regionList
};
}
目前,当我尝试获取经度和纬度的平均值时,我收到一个 http 500 错误,指出处理 LINQ 表达式时出现问题 AsQueryable<Nullable<double>>(new Nullable<double>[]
有什么方法可以在 Entity Framework 的查询中添加平均值?
您需要在中添加 GroupBy LINQ 调用..
我通常 with/feel 更习惯使用方法语法而不是查询语法,所以这可能有点不对:
select ( ... your existing query ...)
group by StateProvinceRegion into g
select new {
StateProvinceRegion = g.Key,
AvgLat = g.Average(x => x.Latitude),
AvgLong = g.Average(x => xLongitude)
}
当您在 LINQ 中对某些内容进行分组时,您不会得到 SQL 这个词意义上的分组; SQL 获取详细信息行,在 GROUP BY 中指定的键列上分组,然后 运行s 在 select 和 returns 中指定的聚合只是键和聚合结果. LINQ 比这更早停止并保留 SQL 丢弃的细节,但您必须直接处理细节以 运行 聚合 -
LINQ 所做的就是将事物列表划分为事物列表,因此 address/lat/long 的原始列表变得像 Dictionary<(address), List<(address, last, long)>>
- 也就是说对于每个唯一地址都有一个关联具有该地址的所有 address/lat/long 列表。
地址存储在g.Key中,列表详细信息为g。这意味着您从密钥中检索地址,并使用典型的 list.Average(element => element.Property)
模式
计算例如平均纬度
在我看来,每家餐厅都有一个地址,而您想要每个州省地区所有餐厅的平均位置。如果您的餐厅有多个地址,则代码不会更改。
我的建议是获取每家餐厅及其地址,然后按 StateProvinceRegion 分组。使用 overload of GroupBy that has a parameter resultSelector.
在 StateProvinceRegion 的结果选择器中计算平均经度/纬度。
var result = dbContext.Restaurant.Join(dbContext.Address,
restaurant => restaurant.RestaurantId, // from every Restaurant take the primary key
address => address.RestaurantId, // from every Address take the foreign key
// to the Restaurant
(restaurant, address) => new // when they match, use the Restaurant and
{ // the Address to make one new object
StateProvinceRegion = restaurant.StateProvinceRegion,
Longitude = address.Longitude,
Latitude = address.Latitude,
})
// Result: per restaurant its StateProvinceRegion and the Longitude and Latitude
// of the Restaurant's Address
// from the joinResult make groups that have equal value for StateProvinceRegion
.GroupBy(joinResult => joinResult.StateProvinceRegion,
// parameter resultSelector: take the StateProvinceRegion
// and all Longitudes / Latitudes that have this StateProvinceRegion
// to make one new object:
(stateProvinceRegion, joinResultsWithThisStateProvinceRegion) => new
{
StateProvinceRegion = stateProvinceRegion,
Longitude = joinResultsWithThisStateProvinceRegion
.Select(joinResult => joinResult.Longitude)
.Average(),
Latitude = joinResultsWithThisStateProvinceRegion
.Select(joinResult => joinResult.Latitude)
.Average(),
});
简单的comme bonjour!
正在尝试为以下列添加平均值:经度和纬度
这是我的 SQL 查询:
SELECT
ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS ID,
r.StateProvinceRegion,
AVG(s.Longitude) AS Longitude,
AVG(s.Latitude) AS Latitude
FROM
RestaurantAddress r
INNER JOIN
Restaurant s ON s.RestaurantId = r.RestaurantId
GROUP BY
StateProvinceRegion
Entity Framework代码:
public VersionResponse GetRegions()
{
var regionList = from restaurantAddress in _context.RestaurantAddress
join restaurant in _context.Restaurant on restaurantAddress.RestaurantId equals restaurant.RestaurantId
select new { restaurantAddress.StateProvinceRegion,
restaurant.Longitude, restaurant.Latitude,
average = (new double?[] { restaurant.Longitude, restaurant.Latitude }).Average()
};
return new VersionResponse()
{
Data = regionList
};
}
目前,当我尝试获取经度和纬度的平均值时,我收到一个 http 500 错误,指出处理 LINQ 表达式时出现问题 AsQueryable<Nullable<double>>(new Nullable<double>[]
有什么方法可以在 Entity Framework 的查询中添加平均值?
您需要在中添加 GroupBy LINQ 调用..
我通常 with/feel 更习惯使用方法语法而不是查询语法,所以这可能有点不对:
select ( ... your existing query ...)
group by StateProvinceRegion into g
select new {
StateProvinceRegion = g.Key,
AvgLat = g.Average(x => x.Latitude),
AvgLong = g.Average(x => xLongitude)
}
当您在 LINQ 中对某些内容进行分组时,您不会得到 SQL 这个词意义上的分组; SQL 获取详细信息行,在 GROUP BY 中指定的键列上分组,然后 运行s 在 select 和 returns 中指定的聚合只是键和聚合结果. LINQ 比这更早停止并保留 SQL 丢弃的细节,但您必须直接处理细节以 运行 聚合 -
LINQ 所做的就是将事物列表划分为事物列表,因此 address/lat/long 的原始列表变得像 Dictionary<(address), List<(address, last, long)>>
- 也就是说对于每个唯一地址都有一个关联具有该地址的所有 address/lat/long 列表。
地址存储在g.Key中,列表详细信息为g。这意味着您从密钥中检索地址,并使用典型的 list.Average(element => element.Property)
模式
在我看来,每家餐厅都有一个地址,而您想要每个州省地区所有餐厅的平均位置。如果您的餐厅有多个地址,则代码不会更改。
我的建议是获取每家餐厅及其地址,然后按 StateProvinceRegion 分组。使用 overload of GroupBy that has a parameter resultSelector.
在 StateProvinceRegion 的结果选择器中计算平均经度/纬度。
var result = dbContext.Restaurant.Join(dbContext.Address,
restaurant => restaurant.RestaurantId, // from every Restaurant take the primary key
address => address.RestaurantId, // from every Address take the foreign key
// to the Restaurant
(restaurant, address) => new // when they match, use the Restaurant and
{ // the Address to make one new object
StateProvinceRegion = restaurant.StateProvinceRegion,
Longitude = address.Longitude,
Latitude = address.Latitude,
})
// Result: per restaurant its StateProvinceRegion and the Longitude and Latitude
// of the Restaurant's Address
// from the joinResult make groups that have equal value for StateProvinceRegion
.GroupBy(joinResult => joinResult.StateProvinceRegion,
// parameter resultSelector: take the StateProvinceRegion
// and all Longitudes / Latitudes that have this StateProvinceRegion
// to make one new object:
(stateProvinceRegion, joinResultsWithThisStateProvinceRegion) => new
{
StateProvinceRegion = stateProvinceRegion,
Longitude = joinResultsWithThisStateProvinceRegion
.Select(joinResult => joinResult.Longitude)
.Average(),
Latitude = joinResultsWithThisStateProvinceRegion
.Select(joinResult => joinResult.Latitude)
.Average(),
});
简单的comme bonjour!