ODAC / Oracle 相当于 Linq to Entities GroupBy FirstOrDefault
ODAC / Oracle Equivalent to Linq to Entities GroupBy FirstOrDefault
我已经多次回到这个问题并在谷歌上搜索了几个小时。即使是现在,写这篇文章,上面建议的重复也没有帮助。
我正在使用以下软件:
- .Net Framework 4.5
- Oracle 11.2.0.3.0(显然)
- Entity Framework 5.0
- MVC 4
- ODAC 12C(不确定这是否是足够的信息)
所以我有这个 table,它包含一个 ID 列(但这不是唯一的!)、一些其他列和一个 "Order" 列(编号 2,0)。我正在尝试 select "Order" 列中编号最小的所有内容按 ID 分组。
这个有效:
query.GroupBy(item => item.Id).Select(item => item.Min(t => t.Order));
但它给了我一个只有整数的 IEnumerable(通常是数字 1 的整个列表)
我需要完整的实体,所以我试试这个:
query.GroupBy(item => item.Id).Select(item => item.OrderBy(t => t.Order).FirstOrDefault());
这给了我以下异常:
"Oracle 11.2.0.3.0 does not support APPLY"
因此,显而易见的解决方案可能是更新上面列出的一些内容。但是:这不是一个选择。
我想我可以 select 唯一键(即 ID、Order 和 StartDate 列,是的...不要问)。但是我该怎么做呢?
这显然是错误的:
query.GroupBy(item => item.Id).Select(item => new { item.Min(t => t.Order), item.Min(t => t.Id), item.Min(t => t.StartDate) });
因为它会 select 所有这些的最小值,而我想要属于具有最低订单号的行的值。所以这就是第一个问题:我该怎么做 select?
第二个问题:如何获得与这些唯一键相关的完整实体?我可以在一个 select 中完成查询吗?我应该使用 list.contains 吗?
有什么建议吗?
您似乎有一个无法在单个 select 语句中查询的 table 结构。您有两个选择:
- 嵌套select
- 内存中过滤器
解决方案 1(嵌套 select)
var intermediateResult = query
.GroupBy(item => item.Id)
.Select(item => new { item.Min(t => t.Order), item.Key })
.ToArray();
这为您提供了一个 (Order, Id) 数组,您可以在后续查询中使用该数组。
解决方案 2(内存过滤器)
var result = query
.GroupBy(item => item.Id)
.Select(item => item.OrderBy(t => t.Order))
.ToArray()
.Select(item => item.First());</code></pre>
这会将所有记录加载到内存中并在结果数组上使用 First()
,这可能不是一个选项,具体取决于行数。
我已经多次回到这个问题并在谷歌上搜索了几个小时。即使是现在,写这篇文章,上面建议的重复也没有帮助。
我正在使用以下软件:
- .Net Framework 4.5
- Oracle 11.2.0.3.0(显然)
- Entity Framework 5.0
- MVC 4
- ODAC 12C(不确定这是否是足够的信息)
所以我有这个 table,它包含一个 ID 列(但这不是唯一的!)、一些其他列和一个 "Order" 列(编号 2,0)。我正在尝试 select "Order" 列中编号最小的所有内容按 ID 分组。
这个有效:
query.GroupBy(item => item.Id).Select(item => item.Min(t => t.Order));
但它给了我一个只有整数的 IEnumerable(通常是数字 1 的整个列表)
我需要完整的实体,所以我试试这个:
query.GroupBy(item => item.Id).Select(item => item.OrderBy(t => t.Order).FirstOrDefault());
这给了我以下异常:
"Oracle 11.2.0.3.0 does not support APPLY"
因此,显而易见的解决方案可能是更新上面列出的一些内容。但是:这不是一个选择。
我想我可以 select 唯一键(即 ID、Order 和 StartDate 列,是的...不要问)。但是我该怎么做呢?
这显然是错误的:
query.GroupBy(item => item.Id).Select(item => new { item.Min(t => t.Order), item.Min(t => t.Id), item.Min(t => t.StartDate) });
因为它会 select 所有这些的最小值,而我想要属于具有最低订单号的行的值。所以这就是第一个问题:我该怎么做 select?
第二个问题:如何获得与这些唯一键相关的完整实体?我可以在一个 select 中完成查询吗?我应该使用 list.contains 吗?
有什么建议吗?
您似乎有一个无法在单个 select 语句中查询的 table 结构。您有两个选择:
- 嵌套select
- 内存中过滤器
解决方案 1(嵌套 select)
var intermediateResult = query
.GroupBy(item => item.Id)
.Select(item => new { item.Min(t => t.Order), item.Key })
.ToArray();
这为您提供了一个 (Order, Id) 数组,您可以在后续查询中使用该数组。
解决方案 2(内存过滤器)
var result = query
.GroupBy(item => item.Id)
.Select(item => item.OrderBy(t => t.Order))
.ToArray()
.Select(item => item.First());</code></pre>
这会将所有记录加载到内存中并在结果数组上使用 First()
,这可能不是一个选项,具体取决于行数。