【问题标题】:GROUP, SUM and DATE DIFFERENCE Entity Framework with LINQ使用 LINQ 的 GROUP、SUM 和 DATE DIFFERENCE 实体框架
【发布时间】:2020-05-20 11:11:51
【问题描述】:

我想将每个客户的所有消费金额相加,然后将结果除以客户在数据库中首次注册的日期;划分的结果将决定最赚钱和最不赚钱的客户。

Customer 表如下所示:

 public class Customer
{
    public int Id { get; set; }
    public string Name{ get; set; }
    public string Surname{ get; set; }
    public int DayOB{ get; set; }
    public int MonthOB{ get; set; }
    public int YearOB{ get; set; }
    public string Genre{ get; set; }
    public string Email { get; set; }
    public string Cellular{ get; set; }
    public bool Privacy { get; set; }
    public bool Profilation{ get; set; }
    public bool Marketing { get; set; }
    public decimal Points{ get; set; }
    public decimal ConversionRate{ get; set; }
    public DateTime RegisterDate{ get; set; }
    public string QRCode { get; set; }
}

而事务表像:

 public class Transaction
{
    public int Id { get; set; }
    public decimal SpentAmount{ get; set; }
    public decimal AddedCoupon{ get; set; }
    public decimal DeductCoupon{ get; set; }
    public DateTime TransactionDate{ get; set; }

    //FOREIGN KEY
    public int CustomerId { get; set; }
    //NAVIGATION
    public Customer Customer { get; set; }
}

目前我已经尝试过这个 LINQ 查询

  public async Task<IHttpActionResult> GetTransactions()
    {
        /*DateTime regDate= from c in db.Customers
                           select c.RegisterDate.Date;*/

        DateTime currentDay= DateTime.UtcNow;

        var query = from c in db.Customers
                    join t in db.Transactions on c.Id equals t.CustomerId
                    where t.Id != null
                    group t by t.CustomerId into ris
                    select new
                    {
                        CustomerId = ris.Key,
                        RegisterDate= ris.Select(c => c.Customer.RegisterDate.Date.Subtract(currentDay)),
                        Sum = ris.Sum(t => t.SpentAmount)
                    };

        return Ok(query.OrderByDescending(ris => ris.Sum));
    }

结果如下:

[
    {
        "CustomerId": 6,
        "RegisterDate": [
            "2020-03-01T00:00:00",
            "2020-03-01T00:00:00"
        ],
        "Sum": 46.00
    },
    {
        "CustomerId": 7,
        "RegisterDate": [
            "2019-11-01T00:00:00",
            "2019-11-01T00:00:00"
        ],
        "Sum": 45.50
    },
    {
        "CustomerId": 5,
        "RegisterDate": [
            "2020-02-01T00:00:00",
            "2020-02-01T00:00:00"
        ],
        "Sum": 31.00
    }
]

CustomerId 的分组部分和 Sum 是正确的结果,但是当我尝试在当天和注册日之间进行差异的部分时,然后将其除以花费的金额,这给了我错误。

【问题讨论】:

  • 您的输出与您显示的代码不匹配。
  • @NetMage 你是什么意思?我又试了一次,结果是这样的。。我唯一改变的是Select语句中的RegisterDay到RegisterDate
  • 它给了我错误 -- 哪个?
  • @GertArnold 它说 LINQ 不接受 DateTime 及其任何方法。肯定那部分不好,但我已经厌倦了看看会发生什么。
  • 您问题中发布的select 既不是RegisterDay 也不是RegisterDate,而是PassedDay。你发错代码了吗?

标签: .net entity-framework linq


【解决方案1】:

抱歉,您不能在 ef.所以你有 2 个变体:

1) 在应用程序的 Web 部分中的 query.ToList() 之后进行计算。我想它会起作用的:

var query = from c in db.Customers
                    join t in db.Transactions on c.Id equals t.CustomerId
                    where t.Id != null
                    group t by t.CustomerId into ris;
                    select new
                    {
                        CustomerId = ris.Key,
                        RegisterDate = ris.Select(c => c.Customer.RegisterDate)
                        Sum = ris.Sum(t => t.SpentAmount)
                    };
var result = query.ToList().Select(x => new {x.CustomerId, PassedDay = RegisterDate.Date.Subtract(currentDay), Sx.Sum });
return Ok(result.OrderByDescending(ris => ris.Sum));

2) Ef 可以使用日期时间比较操作('>'、'='...)和特殊的 dbfunctions(url 中的文档较低)。你可以用它重写代码。

dbfunctions - https://docs.microsoft.com/en-us/dotnet/api/system.data.entity.dbfunctions?view=entity-framework-6.2.0

【讨论】:

  • 不幸的是它不起作用,我无法在“结果”查询中访问 ris:\
  • 我在笔记本上写了代码作为例子,它需要更正才能工作。这就是它最有可能的工作方式。 var result = query.ToList().Select(x => new {x.CustomerId, PassedDay = RegisterDate.Date.Subtract(currentDay), Sx.Sum });我也改了答案码。
  • 是的,我已经纠正了它以尝试使其工作,但 RegisterDate 是一个 IEnumerable 并且它没有 .Date 方法。
  • 事实上我不希望 RegisterDate 出现在列表中,但我想要唯一的日期。目前我被困在这两件事上:\。 PS:谢谢你对我的支持!
猜你喜欢
  • 2012-05-06
  • 2013-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-06
  • 2012-08-28
  • 2017-07-07
相关资源
最近更新 更多