我们如何对从数据库中提取的数据执行分组操作

时间:2019-03-17 20:22:35

标签: c# asp.net-mvc linq

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对它们进行分组,然后从中获取当前日期中特定login_time的最小值email_id。我使用min函数来查找第一个登录名。 我对LINQ非常陌生 我的桌子有字段 1.登录 2.登出 3.电子邮件 4.用户名

每当用户登录时,表就会填充登录时间,注销时间,电子邮件,用户名。 =>我需要基于当前日期的电子邮件对这些详细信息进行分类。 因此该管理员视图页面应仅具有当前日期特定电子邮件的首次登录和最后一次注销。

2 个答案:

答案 0 :(得分:0)

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
    };

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

答案 1 :(得分:0)

您写道:

  

我需要根据电子邮件对它们进行分组,并从中获取当前日期的特定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参数,使其包含其他字段。