用户使用EF和LINQ对事务进行分组

时间:2017-11-02 16:08:50

标签: c# mysql entity-framework linq

我正在使用entity framework core。 (.net core 2.0) 我有以下transactions表结构:

  

列:User1Id(发送自)

     

列:User2Id(已发送至)

     

专栏:Amount

     

专栏:CreatedAt

现在,我想选择所有交易,其中发件人或收件人是当前用户,按发送或接收交易的用户分组,并且仅为每个此类用户选择15个最新交易。

输出的一个例子是(考虑当前用户ID为3):

[
    {
    "user" = "ID 1 here"
    "transactions" : [
            {
                "User1Id" : "ID of user 3 is either here",
                "User2Id" : "or here",
                "Amount" : 100,
                "CreatedAt" : 10.01.2017
            },{
                "User1Id" : "ID of user 3 is either here",
                "User2Id" : "or here",
                "Amount" : 200,
                "CreatedAt" : 09.01.2017
            }
        ]
    },{
    "user" = "ID 2 here"
    "transactions" : [
            {
                "User1Id" : "ID of user 3 is either here",
                "User2Id" : "or here",
                "Amount" : 100,
                "CreatedAt" : 01.01.2017
            }
        ]
    }
]

对于LINQ来说,这看起来太复杂了。不过,这是我提出的最接近的结果:

var userId = User.GetUserId(); // current user ID
var result = _context.Transactions
   .AsNoTracking()
   .Where(t => t.User1Id == userId || t.User2Id == userId)
   .Select(u => new
   {
       Transaction = u,
       User = (u.User1Id == userId) ? u.User1Id : u.User2Id
   })
   .GroupBy(g => g.User)
   .Select(u => new
   {
       User = u.Key,
       Transaction = u.ToList()
   });

首先 - 这个LINQ产生警告:

  

警告:Microsoft.EntityFrameworkCore.Query [200500]         LINQ表达式' GroupBy(IIF(([t] .User1Id == __userId_2),[t] .User1Id,[t] .User2Id),new<> f__AnonymousType2`2(Transaction = [t], User = IIF(([t] .User1Id == __userId_2),[t] .User1Id,[t] .User2Id)))'无法翻译,将在本地进行评估。

其次,目前没有考虑交易的订购,也没有限制每个用户的交易数量。

最后,一些数据是重复的(例如用户ID),因为u.Key.ToList()只是将先前组中的任何值都转换为列表。

我正在考虑为这种情况编写自定义SQL。有没有合适的LINQ解决方案?

1 个答案:

答案 0 :(得分:0)

本来只是作为评论,但在伪代码中可能不太容易理解。有时KISS(保持简单......)是最好的方式。当然,这纯粹是意见。对我来说,我会考虑做这样的事情:

Transactions.Where(t => t.User1Id == userId).Select(t => new { user = t.User2Id, transaction = t})
    .Union(Transactions.Where(t => t.User2Id == userId).Select(t => new { user = t.User1Id, transaction = t }))
    .OrderBy(x => x.transaction.CreatedAt)
    .Take(15)
    .ToList()
    .GroupBy(x => x.user);