【问题标题】:How do we perform groupby operation on data fetched from a database我们如何对从数据库中获取的数据执行 groupby 操作
【发布时间】:2019-03-17 20:22:34
【问题描述】:
string date = DateTime.Today.Date.ToShortDateString();
var grouped = from a in db.Logs
    group a by a.email
    into g
    select new
    {
        intime = (from x in db.Logs where x.date == date && x.email == "" select x.login).Min();
        outime = (from x in db.Logs where x.date == date && x.email == "" select x.login).Min()

    };
return View();

我正在使用具有emaillogin_time 的表格。

我需要根据email 对它们进行分组,然后我需要获取当前日期特定email_id 的最小login_time。我使用min 函数查找第一个登录。 我对 LINQ 很陌生 我的表有字段 1.登录 2.注销 3.电子邮件 4.用户名

每当用户登录时,表都会填充登录时间、注销时间、电子邮件、用户名。 =>我需要根据当前日期的电子邮件对这些详细信息进行分类。 这样管理员视图页面应该只有当前日期特定电子邮件的第一次登录和最后一次注销。

【问题讨论】:

  • 您的意思是用 C# 标记这个吗?这不是 C。
  • 您应该让数据库进行分组——您的应用程序不需要这样做。如何使用 LINQ 是一个单独的讨论。还有其他人可以帮助你(我不能——我没有使用过 LINQ)。
  • 我得到了数据库,并将它们转换为tolist;

标签: c# asp.net-mvc linq


【解决方案1】:

你写道:

我需要根据电子邮件对它们进行分组,并从中获取当前日期特定 email_id 的最小 login_time。

为此,我会使用Queryable.GroupBy with an ElementSelector

DateTime selectionDate = DateTime.UtcNow.Date;  // or any other date you want to use


var result = db.Logs
    // Keep only logs that have an e-mail on the selection date:
    .Where(log => log.LogInTime == selectionDate)

    // Group all remaining logs into logs with same email
    .GroupBy(log => log.email,

    // element selector: I only need the LoginTimes of the Logs
    log => log.LoginTime,

    // result selector: take the email, and all logInTimes of logs 
    // with this email to make a new object
    (email, logInTimesForThisEmail) =>  new
    {
        Email = email, // only if desired in your end result

        // Order the loginTimes and keep the first,
        // which is the min login time of this email on this date
        MinLoginTimeOnDate = logInTimesForThisEmail
            .OrderBy(logInTime => loginTime)
            .FirstOrDefault(),

您的示例代码显示您还希望在所选日期获得最长登录时间。使用单独的 Select,因此您只需对元素进行一次排序:

(email, logInTimesForThisEmail) =>  new
{
    Email = email, // only if desired in your end result
    LogInTimes = logInTimesForThisEmail
        .OrderBy(loginTime => loginTime);
})
.Select(groupResult => new
{
    Email = groupResult.Email,
    MinTime = groupResult.LogInTimes.FirstOrDefault(),
    MaxTime = groupResult.LogInTimes.LastOrDefault(),
});

如果您需要的字段不仅仅是电子邮件和登录时间,请更改 GroupBy 的 ElementSelector 参数,使其也包含这些其他字段。

【讨论】:

    【解决方案2】:
    string date = DateTime.Today.Date.ToShortDateString();
    var grouped = from a in db.Logs.ToList()
        where a.date == date
        group a by a.email
        into g
        let ordered = g.OrderBy(x => x.date).ToList()
        let firstLogin = ordered.First()
        let lastLogin = ordered.Last()
        select new
        {
            first_login_time = firstLogin.login_time,
            first_login = firstLogin.login,
            last_login_time = lastLogin.login_time,
            last_login = lastLogin.login        
        };
    

    更新

    管理视图页面应该只有第一次登录和最后一次注销 当前日期的特定电子邮件。

    string date = DateTime.Today.Date.ToShortDateString();
    var grouped = from a in db.Logs.ToList()
        where a.login.Date == date
        group a by a.email
        into g
        let firstLogin = g.OrderBy(x => x.login).First() // order by login time and get first
        let lastLogout = g.OrderBy(x => x.logout).Last() // order by lotgout time and get last
        select new
        {
            email: g.Key,
            first_login = firstLogin.login, // first login
            last_logout = lastLogin.logout // last logout
        };
    

    我希望您的 loginlogout 字段具有 datetime 类型。你仍然没有得到更清楚的问题。当我要求你获取表模式时,我想你会让我这样想:

    CREATE TABLE [dbo].[Logs](
        [username] [nvarchar](4000) NOT NULL,
        [email] [nvarchar](4000) NOT NULL,
        [login] [datetime] NULL,
        [logout] [datetime] NULL
    )
    

    或者类声明

    public class Log {
      public string email {get; set; }
      public string username {get; set; }
      public DateTime login {get; set; }
      public DateTime logout {get; set; }
    
    }
    

    你可以学习如何提问

    更新 2

    假设我有 3 封不同的电子邮件。如果他们访问了我的应用程序 记录登录时间和注销时间。

    Table[Login_details]
    id  employee    date        login   logout  email
    1   ShobaBTM    2019-03-18  16:12   16:12   shobabtm@gmail.com
    2   neymarjr    2019-03-18  16:22   16:22   neymar@gmail.com
    3   Cristiano   2019-03-18  16:23   16:23   cr7@gmail.com
    4   neymarjr    2019-03-18  16:25   16:25   neymar@gmail.com
    5   neymarjr    2019-03-18  16:30   16:32   neymar@gmail.com
    6   neymarjr    2019-03-18  16:42   16:45   neymar@gmail.com
    

    在管理员视图中我应该有这个

    1   ShobaBTM    2019-03-18  16:12   16:12   
    2   Cristiano   2019-03-18  16:23   16:23
    3   neymarjr    2019-03-18  16:25   16:45   
    

    好吧,试试这个:

    string date = DateTime.Today.Date.ToShortDateString();
    var grouped = from a in db.Logs.ToList()
        where a.date == date
        group a by new { a.employee, a.date }
        into g
        let firstLogin = g.OrderBy(x => TimeSpan.ParseExact(x.login, "hh\\:mm")).First() // order by login time and get first
        let lastLogout = g.OrderBy(x => TimeSpan.ParseExact(x.logout, "hh\\:mm")).Last() // order by logout time and get last
        select new
        {
            employee = g.Key.employee,
            date = g.Key.date,
            first_login = firstLogin.login, // first login
            last_logout = lastLogin.logout // last logout
        };
    

    该代码有效吗?如果没有 - 究竟会发生什么?

    【讨论】:

    • 我需要根据电子邮件对它们进行分组,然后我需要获取当前日期的特定 email_id 的 First login_time(让它在今天)。
    • 我编辑答案。您需要提供Logs 表架构,没有人知道您的字段名称。
    • 给定的。请检查一下
    • 你太棒了。工作得很好。谢谢。建议一种在这方面做得很好的方法
    • 擅长什么? :) C#、LINQ、ASP.NET MVC?您必须阅读文档、示例、尝试编写自己的代码、进行试验、在 stackoverflow 中搜索答案等等。清晰会随着经验而来。我自己在 C# 方面的经验大约是 10 年,所以像你这样的问题对我来说很简单 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 2012-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多