Sum方法返回long值

时间:2017-02-25 12:56:09

标签: c# linq

我正在尝试将LINQ Sum方法结果作为long

long TotalWeight = _ctx.ProductsToUsers.Where(pu => pu.UserId == subDetails.user.Id).SelectMany(pu => pu.CropData).Sum(cd => cd.Weight);

在上面的代码段中,Weight的类型为int。现在我想添加所有权重并将它们存储在TotalWeight变量中。问题是总和可能会超出int的范围,因此我必须将其转换为long

我尝试了以下代码:

long TotalWeight = _ctx.ProductsToUsers.Where(pu => pu.UserId == subDetails.user.Id).SelectMany(pu => pu.CropData).Sum(cd => (long)cd.Weight);

但是上面的代码给我的错误是unable to cast object of type 'system.int32' to type 'system.int64'。如何在不丢失数据的情况下将Weight的总和转换为long

Weight转换为long类型是不可行的解决方案,因为单Weight永远不会超过int范围。

以下是CropData类的实现。

public class CropData
{
    [Required]
    public int ProductToUserId { get; set; }
    [Required]
    public DateTime DateTime { get; set; }
    [Required]
    public int Weight { get; set; }

}

2 个答案:

答案 0 :(得分:3)

我可以给你一个可行的答案:

long TotalWeight = _ctx.ProductsToUsers.Where(pu => pu.UserId == subDetails.user.Id).SelectMany(pu => pu.CropData.Weight).Cast<long>().Sum();

但是,我更感兴趣的是您的解决方案无法正常工作。我们来看看:

long TotalWeight = _ctx.ProductsToUsers.Where(pu => pu.UserId == subDetails.user.Id).SelectMany(pu => pu.CropData).Sum(cd => (long)cd.Weight);

它匹配Enumerable.Sum

的签名
public static long Sum<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, long> selector
)

并且在运行时,将int的实例转换为long的实例是完全合法的。问题在于您的ORM实施IQueryable。 Linq to Entities(或任何你的ORM使用的)无法正确解释演员

cd => (long)cd.Weight

导致问题的是您的ORM这一事实解释了为什么有几个人报告它对他们有效。

另一种解决方法是抛出ToArray()调用,告诉你的ORM将所有CropData个对象加载到内存中。然后将对您的内存中对象执行Linq操作:

long TotalWeight = _ctx.ProductsToUsers.Where(pu => pu.UserId == subDetails.user.Id).SelectMany(pu => pu.CropData)
    .ToArray()
    .Sum(cd => (long)cd.Weight);

这意味着您还要下载未使用的字段ProductToUserIdDateTime - 这里可能不是问题,但如果您的CropData对象更大,那么会受到性能影响。因此,无论您决定做什么,我建议您使用SelectMany(pu => pu.CropData.Weight),这会将您的数据传输费用降至最低。

答案 1 :(得分:1)

.navbar .navbar-nav > li > a {
padding: 27px 15px;
}