我有这个LINQ查询:
ArrayList arr = new ArrayList();
var data = conn.SCOT_DADOS.OrderByDescending(x => x.DATE)
.GroupBy(r => r.USER)
.ToList();
foreach (var item in data)
{
var itemdata = item.Where(r => r.DATE == item.Max(s => s.DATE));
var name = svc.GetUserName(itemdata.Select(r => r.USER).First().ToString());
var value = itemdata.Select(r => r.VALUE).First();
var date = itemdata.Select(r => r.DATE).First().ToString("dd/MM/yyyy HH:mm:ss");
arr.Add( new{ NAME = name, DATE = date, VALUE = value} );
}
此代码会根据DATE
为USER
提供最新结果。
但LINQ查询正在从用户中选择所有数据,然后我在foreach循环中获取最新数据。
有没有办法只获取LINQ查询中的最后一个数据,所以我不必每次都获取所有用户数据?
我试过这个:
var data = conn.SCOT_DADOS.OrderByDescending(x => x.DATE)
.GroupBy(r => r.USER)
.First()
.ToList();
然后将item
视为对象,而不是在其上运行选择。
它为我提供了个人用户的所有数据,这不是我想要的。
可以做些什么?
编辑1:
如果我尝试交换OrderByDescending
和GroupBy
:
错误CS1061'IGrouping'不包含 'DATE'的定义,没有扩展方法'DATE'接受第一个 可以找到'IGrouping'类型的参数(是 你错过了使用指令或程序集引用?)
编辑2:
这是一些示例数据(列名不相同,因为我为这个问题翻译了它们):
根据提供的数据,我得到了结果:
答案 0 :(得分:2)
我有点困惑,但是你的尝试First()
认为你的意思是:
conn.SCOT_DADOS.GroupBy(item => item.User)
.Select(grp => grp.OrderByDescending(i => t.Date).First());
这将为每个 User
检索仅
仅交换GroupBy
和OrderByDescending
的原因是不够的,而您需要Select
的原因是,您将可枚举的数据归为IEnumerable<IGrouping<User,YourType>>
。每个IGrouping
实际上都是一个集合,所以你需要Select
只需要你想要的1个项目。
另一种方法是将Select
替换为:
.SelectMany(grp => grp.OrderByDescending(i => t.Date).Take(1))
IMO第一个更干净,但第二个是你需要每个用户N个第一项
在上面的查询中,您还可以添加foreach
循环中的内容:
conn.SCOT_DADOS.GroupBy(item => item.User)
.Select(grp => grp.OrderByDescending(i => t.Date).First())
.AsEnumerable()
.Select(item => new {
Name = svc.GetUserName(item.User),
Value = item.Value,
Date = item.Date.ToString("dd/MM/yyyy HH:mm:ss")
}).ToList();
使用AsEnumerable()
是为了在最后Select()
之前调用要对数据库执行的查询,GetUserName
使用DateTime
方法,而该方法是不知道的。 Oracle数据库
将GroupBy
表示为字符串的IMO不是一个好方法..
更新 - 您收到的错误:
Oracle 11.2.0.3.0不支持应用
对于此版本的Oracle,它似乎不支持Select
通过linq undefined is not a function (evaluating '_this3.refs.Second.focus()')
。见Linq to Entities Group By (OUTER APPLY) “oracle 11.2.0.3.0 does not support apply”。
建议在数据库中为此创建一个视图,然后使用linq选择该视图。这就是我要去的地方
答案 1 :(得分:2)
如果(USER,DATE)对的组合是唯一的(在查看样本数据时似乎就是这种情况),则可以将需求减少到
如果没有其他记录使用相同的USER以及之后的DATE
,则返回每条记录
可以转换为以下LINQ查询:
var result = conn.SCOT_DADOS
.Where(r => !conn.SCOT_DADOS.Any(r2 => r2.USER == r.USER && r2.Date > r.Date))
// end of Db Query
.AsEnumerable()
.Select(r => new
{
Name = svc.GetUserName(r.User),
Value = r.Value,
Date = r.Date.ToString("dd/MM/yyyy HH:mm:ss")
}).ToList();
答案 2 :(得分:0)
试试这个
conn.SCOT_DADOS.GroupBy(x => x.User).Select(x => new
{
User = x.Key,
Date = list.Where(y => y.User == x.Key).Max(y => y.Date)
});