SELECT ulcch.ID, ulcch.UserLoginHistoryID, ulcch.StatusID,
ulcch.ClientModuleID, ulcch.DeviceState, ulcch.UpdatedAt, ulcch.CreatedAt
FROM UserLoginClientConnectionHistory AS ulcch INNER JOIN
(SELECT MAX(CreatedAt) AS maxCreatedAt
FROM UserLoginClientConnectionHistory AS ulcch1
GROUP BY UserLoginHistoryID) AS m ON m.maxCreatedAt = ulcch.CreatedAt
每天可以对此登录表中的“设备状态”进行多次更新。此查询返回每天的最后一个唯一值。
我希望将其重写为Lambda语句。这是我得到了多远,我不知道我是否在正确的轨道上,而我的Max()
正在抛出一个类型错误,可能是因为该组正在制作另一个列表或其他内容......
希望你能从我的对象例子中解决它....:S
userLogin.UserLoginClientConnectionHistories.Where(x => x.CreatedAt ==
userLoginClientConnectionHistoryRepository.GetAll(
GenericStatus.Active).GroupBy(y => y.UserLoginHistoryID).Max(y => y.CreatedAt));
答案 0 :(得分:1)
这是作为lambda的内部连接部分。我假设CreatedAt是一个dateTime。
UserLoginClientConnectionHistory
.GroupBy(ulcch1 =>
新
{
Name = ulcch1.Name
})
。选择(g =>
新
{
maxCreatedAt =(DateTime?)(g.Max(p => p.CreatedAt))
})
答案 1 :(得分:1)
我认为您希望按CreatedAt
而不是UserLoginHistoryID
进行分组:
var q = userLogin.UserLoginClientConnectionHistories
.GroupBy(h => h.CreatedAt)
.OrderByDescending(g => g.Key) // Sort by CreatedAt
.First()
.Select(h => new { h.Id, h.UserLoginHistoryID, ... });
这将返回共享最新UserLoginClientConnectionHistory
值的CreatedAt
条目集。
答案 2 :(得分:1)
我认为这可以满足您的需求:
var result = userLogin.UserLoginClientConnectionHistories
.GroupBy(y => new { Id = y.UserLoginHistoryID, Day = y.CreatedAt.Date })
.Select(x => new
{
Id = x.Key.Id,
Day = x.Key.Day,
MostRecent = x.Max(y => y.CreatedAt)
});
这是一个测试平台:
public class Program
{
class LoginEntry
{
public int UserLoginHistoryID { get; set; }
public DateTime CreatedAt { get; set; }
}
class UserLogin
{
public List<LoginEntry> UserLoginClientConnectionHistories = new List<LoginEntry>();
}
public static void Main(string[] args)
{
UserLogin userLogin = new UserLogin();
userLogin.UserLoginClientConnectionHistories = new List<LoginEntry> {
new LoginEntry {UserLoginHistoryID = 1, CreatedAt = new DateTime(2009, 1, 1, 3, 0 ,0)},
new LoginEntry {UserLoginHistoryID = 1, CreatedAt = new DateTime(2009, 1, 1, 15, 0 ,0)},
new LoginEntry {UserLoginHistoryID = 1, CreatedAt = new DateTime(2009, 1, 3, 11, 0 ,0)},
new LoginEntry {UserLoginHistoryID = 1, CreatedAt = new DateTime(2009, 1, 1, 10, 0 ,0)},
new LoginEntry {UserLoginHistoryID = 2, CreatedAt = new DateTime(2009, 1, 3, 4, 0 ,0)},
new LoginEntry {UserLoginHistoryID = 2, CreatedAt = new DateTime(2009, 1, 3, 5, 0 ,0)},
};
var result = userLogin.UserLoginClientConnectionHistories
.GroupBy(y => new { Id = y.UserLoginHistoryID, Day = y.CreatedAt.Date })
.Select(x => new
{
Id = x.Key.Id,
Day = x.Key.Day,
MostRecent = x.Max(y => y.CreatedAt)
});
foreach (var item in result)
{
Console.WriteLine("User {0}, day {1}, most recent {2}",
item.Id,
item.Day,
item.MostRecent);
}
}
}
输出:
User 1, day 01-01-2009 00:00:00, most recent 01-01-2009 15:00:00
User 1, day 03-01-2009 00:00:00, most recent 03-01-2009 11:00:00
User 2, day 03-01-2009 00:00:00, most recent 03-01-2009 05:00:00
答案 3 :(得分:0)
感谢所有帮助人员,我已经投了你们所有人,但你们不会相信,但几个小时后我搜索了一个程序将SQL转换为LINQ,令我惊讶的是发现了一个名为“{ {3}}”。听起来很疯狂,并没有想到会走得太远,但它运作得很完美......如果有其他人被卡在同一条船上,绝对值得一试这个应用......
检查它返回的庞大查询!在分析之后,不要认为它有额外膨胀吗?任何人都有任何优化提示或发现任何不必要的代码?
moduleDeviceStates = from ulh in user.UserLoginHistories
join ulcch in userLogin.UserLoginClientConnectionHistories on new { ID = ulh.ID } equals new { ID = ulcch.UserLoginHistoryID }
join cm in clientModuleRepository.GetAll(GenericStatus.Active) on new { ClientModuleID = ulcch.ClientModuleID } equals new { ClientModuleID = cm.ID }
join mo in moduleRepository.GetAll(GenericStatus.Active) on new { ModuleID = cm.ModuleID } equals new { ModuleID = mo.ID }
join m in
(
(from ulcch1 in userLogin.UserLoginClientConnectionHistories
group ulcch1 by new
{
ulcch1.UserLoginHistoryID
} into g
select new
{
maxCreatedAt = g.Max(p => p.CreatedAt)
})) on new { maxCreatedAt = ulcch.CreatedAt } equals new { maxCreatedAt = m.maxCreatedAt }
select new ModuleDeviceState()
{
ModuleID = mo.ID,
Name = mo.Name,
DeviceState = (State.DeviceState)ulcch.DeviceState,
CreatedAt = ulcch.CreatedAt
};
为你的帮助dahlbyk干杯,但我确实希望对UserLoginHistoryID进行分组,在深入研究lambda等效之前,我已经在SQL中确认了我的查询:)谢谢。
<小时/> @Mark感谢您抽出时间回复,是的,我每天都按照每个用户[userloginhistory ...进而包含一个用户ID)的[last]条目,并将我的sql导出到linq查询确实产生了我想要的东西(这可以在下面的查询结果中看到;这就是我想要的。你每天看到双重条目的原因是因为还附加了ClientModule的..所以我真的想要所有客户端模块,每天每次登录条目 - 这么难在讨论论坛上获得编程要求argh!)也许你的做法完全相同(看起来如果我正确地阅读你的输出)只是更精简。
看到我不太了解你用GroupBy
和Select
完成的那个anon投射,但现在我看到它,这是有意义的。我可能会给你一个机会。希望我能给它一个调整,包括每天不同的ClientModule。所以无论如何..这里是我的SQL的查询结果,实际上是我通过自己的lambda得到的结果:
ID UserLoginHistoryID StatusID ClientModuleID DeviceState UpdatedAt CreatedAt
277 62 1 1 4 NULL 2009-10-31 13:28:59.003
278 62 1 16 4 NULL 2009-10-31 13:28:59.003
331 65 1 1 4 NULL 2009-10-31 17:13:28.333
332 65 1 16 4 NULL 2009-10-31 17:13:28.333
<小时/> 更新标记:您好了,经过对查询的几次调整后,我可以在两个lambda语句之间生成相同的.NET对象图。这是我现在将使用的,因为它比自动生成的更简化,更容易理解,我将奖励你积分:)
我向小组添加了一些条目,因为我需要为new
ModuleDeviceState
课程添加。
moduleDeviceStates = userLogin.UserLoginClientConnectionHistories
.GroupBy(y => new { Id = y.UserLoginHistoryID,
CreatedAt = y.CreatedAt.Date,
ModuleID = y.ClientModule.ModuleID,
ModuleName = y.ClientModule.Module.Name,
DeviceState = y.DeviceState })
.Select(x => new ModuleDeviceState()
{
ModuleID = x.Key.ModuleID,
Name = x.Key.ModuleName,
DeviceState = (State.DeviceState)x.Key.DeviceState,
CreatedAt = x.Max(y => y.CreatedAt)
});