엔티티 그룹 기준(OUTER APPLY)에 대한 링크 "oracle 11.2.0.3.0은 적용을 지원하지 않습니다."
아래에 제품 목록을 조회하는 코드 샘플이 있습니다.
var productResults = Products.Where((p) => refFilterSequence.Contains(p.Ref))
.GroupBy(g => g.Code, (key, g) => g.OrderBy(whp => whp.Ref).First()).ToList();
이것은 예상대로 정확히 작동하며 in 메모리 컬렉션을 사용할 때는 원하는 4개의 행을 반환하지만 Oracle 데이터베이스에 대해 실행할 때는 다음과 같습니다.
.GroupBy(g => g.Code, (key, g) => g.OrderBy(whp => whp.Ref).First())
사용해야 한다는 오류가 발생합니다.FirstOrDefault
Oracle 데이터베이스에서는 지원되지 않습니다.oracle 11.2.0.3.0이 apply를 지원하지 않습니다라는 오류가 발생했습니다.Google은 CodePlex: https://entityframework.codeplex.com/workitem/910 에서 이를 확인할 수 있습니다.
이 문제는 다음 이진 파일을 사용할 때 발생합니다.
- 엔티티 프레임워크 6.0.0.0
- Oracle.ManagedDataAccess 4.121.2.0
- Oracle.ManagedDataAccess.엔티티 프레임워크 6.121.2.0
- .Net Framework 4.5.1
데이터베이스는 Oracle 11.2.0.3.0 데이터베이스입니다.
생성된 sql은 11.2.0.3.0 버전의 Oracle에서 지원되지 않는 OUTER APPLY(아래 이미지 참조)를 사용하는데 왜 EF/Oracle입니까?Managed Data Access를 사용하려고 합니까?EF에게 APPLY 키워드를 사용하지 말라고 할 수 있는 방법이 있습니까?
아래 페이지에는 Oracle 12c Release 1에 APPLY 지원이 추가되었다고 나와 있지만 GROUP BY 작업을 위해 모든 데이터베이스를 업데이트할 수는 없습니다.http://www.oracle.com/technetwork/database/windows/newfeatures-084113.html
이 문제는 알려진 문제(Entity Framework에 대한 SqlClient의 알려진 문제)인 것 같습니다.
다음은 출력 쿼리에 CROSS APPLE 및/또는 OUTER APPLE 연산자가 포함될 수 있는 몇 가지 일반적인 시나리오입니다.
- LINQ는 요소 선택기를 수락하는 그룹화 방법을 사용하는 쿼리를 수행합니다.
보기 작성에 의존하기 전에(여러 데이터베이스에 보기를 작성해야 할 경우) 다른 솔루션을 볼 수 있는 사람이 있습니까?
이 데이터베이스 버전에 대해 원하는 작업을 수행할 수 있는 SQL은 다음과 같습니다.
select *
from ( select RANK() OVER (PARTITION BY sm.product ORDER BY refs.map) ranking, sm.*
from schema.table sm,
(
select 'R9' ref, 0 map from dual
union all
select 'R1' ref, 1 map from dual
union all
select 'R6' ref, 2 map from dual
) refs
where sm.ref= refs.ref
) stock
where ranking = 1
코드는 결국 웹 API의 OData 컨트롤러에 전달되는 서비스 클래스에 있게 됩니다.아래 예제는 데모 데이터를 사용하고 실제 데이터베이스에는 700,000개의 레코드가 있으므로 쿼리 실행을 피하고 OData가 페이지 제한 및 추가 필터링을 처리하도록 하고 싶습니다.
using System;
using System.Collections.Generic;
using System.Linq;
namespace DemoApp
{
class Program
{
public class Product
{
public string Ref { get; set; }
public string Code { get; set; }
public int Quantity { get; set; }
}
//demo data
static readonly List<Product> Products = new List<Product>
{
new Product { Ref = "B2", Code = "ITEM1", Quantity = 1},
new Product { Ref = "R1", Code = "ITEM1", Quantity = 2},
new Product { Ref = "R9", Code = "ITEM1", Quantity = 3},
new Product { Ref = "R9", Code = "ITEM2", Quantity = 4},
new Product { Ref = "R6", Code = "ITEM2", Quantity = 5},
new Product { Ref = "B2", Code = "ITEM3", Quantity = 6},
new Product { Ref = "R1", Code = "ITEM3", Quantity = 7},
new Product { Ref = "R9", Code = "ITEM3", Quantity = 8},
new Product { Ref = "B2", Code = "ITEM4", Quantity = 9},
new Product { Ref = "X3", Code = "ITEM4", Quantity = 10},
new Product { Ref = "B8", Code = "ITEM5", Quantity = 10},
new Product { Ref = "R6", Code = "ITEM5", Quantity = 12},
new Product { Ref = "M2", Code = "ITEM5", Quantity = 13},
new Product { Ref = "R1", Code = "ITEM5", Quantity = 14},
};
static void Main(string[] args)
{
// this array is of variable length, and will not always contain 3 items.
var refFilterSequence = new List<string> {"R9", "R1", "R6"};
var results = GetProductsForODataProcessing(refFilterSequence);
// some further filtering may occur after the queryable is returned.
// the actual implmentation is an OData Web API, so filters, expansions etc could be added.
//results = results.Where(p => p.Quantity > 2);
results.ToList().ForEach(p => Console.WriteLine("RANK:{0}\tREF:{1}\tCode:{2}\tQty:{3}", "?", p.Ref, p.Code, p.Quantity));
Console.ReadLine();
}
static IQueryable<Product> GetProductsForODataProcessing(List<string> filterSequence )
{
var productResults = Products.Where((p) => filterSequence.Contains(p.Ref))
.GroupBy(g => g.Code, (key, g) => g.OrderBy(whp => whp.Ref).First()).AsQueryable();
return productResults;
}
}
// Example Output
// .......................
// REF:R1 Code:ITEM1 Qty:2
// REF:R6 Code:ITEM2 Qty:3
// REF:R1 Code:ITEM3 Qty:7
// REF:R1 Code:ITEM5 Qty:14
당신이 직접 쿼리를 작성할 수 있었기 때문입니다.저장 프로시저를 생성하여 Entity Framework에서 SP를 호출할 수 있습니다.
GroupBy 이전에 ToArray를 실행하여 메모리에서 실행할 수 있습니다.최적의 성능은 아니지만 작동해야 합니다.
var productResults = Products.Where((p) => refFilterSequence.Contains(p.Ref)).ToArray()
.GroupBy(g => g.Code, (key, g) => g.OrderBy(whp => whp.Ref).First()).ToList();
Oracle 11은 APPLY를 지원하지 않습니다.그러나 Oracle 12는 이를 지원합니다.
언급URL : https://stackoverflow.com/questions/29705013/linq-to-entities-group-by-outer-apply-oracle-11-2-0-3-0-does-not-support-appl
'programing' 카테고리의 다른 글
스프링 부트를 사용하여 Zuul에 대한 디버그 정보를 보려면 어떻게 해야 합니까? (0) | 2023.07.21 |
---|---|
MySQL 파티셔닝을 생성한 후 이를 활용하려면 특수 쿼리가 필요합니까? (0) | 2023.07.21 |
Oracle에 대해 실행된 쿼리를 보려면 어떻게 해야 합니까? (0) | 2023.07.21 |
목록의 Python os.path.join() (0) | 2023.07.21 |
열 이름을 기준으로 여러 열 삭제 (0) | 2023.07.21 |