【问题标题】:Sum in child collection子集合中的总和
【发布时间】:2017-01-16 13:56:36
【问题描述】:

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

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 子句 'Project1'.'Id'。这是 MySQL 的一个老错误。

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

如果可以正常工作,我正在使用内联,但会生成一个非常丑陋的 SQL,其中包含大量内部查询和重复的选择语句。

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

有没有更好的方法来避免 DefaultIfEmpty?

【问题讨论】:

    标签: mysql entity-framework-6


    【解决方案1】:

    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 上测试

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-14
      • 2010-09-08
      相关资源
      最近更新 更多