gpt4 book ai didi

mysql - 子集合中的总和

转载 作者:行者123 更新时间:2023-11-29 06:05:57 25 4
gpt4 key购买 nike

当我对空子集合的值求和时,将 MySQL 与 EF6 结合使用会引发异常,因为 MySQL 不支持 DefaultIfEmpty,如 bug #80127 中相关.

public class Foo
{
public int Id { get; set; }
public decimal Total { get; set; }
public virtual IList<Bar> Bars { get; set; }
}

public class Bar
{
public int Id { get; set; }
public int FooId { get; set; }
public virtual Foo Foo { get; set; }
public decimal Received { get; set; }
}

将推荐的方法与 DefaultIfEmpty 一起使用会引发异常,where clausule 'Project1'.'Id' 无效。这是MySQL的一个老bug。

var result = db.Foo.Select(f => new {
Total = f.Total,
Received = f.Bars.Select(b => b.Received).DefaultIfEmpty().Sum()
});

我正在使用内联 if 可以正常工作,但会生成一个非常难看的 SQL,其中包含大量内部查询和重复的 select 语句。

var result = db.Foo.Select(f => new {
Total = f.Total,
Received = f.Bars.Any() ? f.Bars.Sum(b => b.Received) : 0
});

是否有更好的方法来避免 DefaultIfEmpty?

最佳答案

我通常更喜欢的 DefaultIfEmpty 的替代方法是使用转换运算符将不可空类型提升为可空类型,这(甚至)适用于 MySQL 连接器。

然后解决方案取决于您的接收器类属性类型。

最好是你能收到一个可以为空的结果,在这种情况下查询很简单:

var result = db.Foo.Select(f => new {
Total = f.Total,
Received = f.Bars.Sum(b => (decimal?)b.Received)
});

如果需要是不可空类型,可以使用空合并运算符

var result = db.Foo.Select(f => new {
Total = f.Total,
Received = f.Bars.Sum(b => (decimal?)b.Received) ?? 0
});

但生成的 SQL 查询很丑陋且效率低下。

在这种情况下你能做的最好的事情就是使用(一个非常烦人的)双选技巧:

var result = db.Foo.Select(f => new {
f.Total,
Received = f.Bars.Sum(b => (decimal?)b.Received)
})
.Select(r => new {
r.Total,
Received = r.Received ?? 0
};

或者(更好的)带有 let 子句的查询语法:

var result =
from f in db.Foos
let received = f.Bars.Sum(b => (decimal?)b.Received)
select new { f.Total, Received = received ?? 0 };

使用 MySQL Connector/Net 6.9.8 在最新的 EF6.1.3 上测试

关于mysql - 子集合中的总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41678020/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com