2013-08-20 7 views
12

LINQKit을 공유 데이터 액세스 계층에 통합하려고 시도했지만로드 블록에 부딪혔습니다. ExpandableQuery을 사용하여 중첩 된 쿼리를 만들 때 식 구문 분석기는 ExpandableQuery의 랩핑을 올바르게 제거하고 유효한 SQL 쿼리를 구성 할 수 없습니다. throw 된 오류 :LINQKit : 엔티티에 LINQ의 ExpandableQuery 중첩

System.NotSupportedException : 'Store'형식의 상수 값을 만들 수 없습니다. 이 문맥에서는, 원시 형 또는 열거 형만이 지원되고 있습니다.

다음 샘플 프로그램을 사용하면이 문제를 쉽게 재구성 할 수 있으며 테이블의 AsExpandable() 호출과 분명하게 분리되어 있습니다. 당신이 AsExpandable() 호출을 제거

class Program 
{ 
    static void Main(string[] args) 
    { 
     Database.SetInitializer<MyContext>(null); 
     var cs = MY_CONNECTION_STRING; 
     var context = new MyContext(cs); 

     var table = (IQueryable<Store>)context.Set<Store>(); 
     var q = table 
      .AsExpandable() 
      .Select(t => new {Id = t.StoreId, less = table.Where(tt => tt.StoreId > t.StoreId) }) 
      .Take(1) 
      .ToArray(); 
    } 
} 

public class MyContext : DbContext 
{ 
    public MyContext(string connection) : base(connection) {} 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Store>(); 
     base.OnModelCreating(modelBuilder); 
    } 
} 

[Table("stores")] 
public class Store 
{ 
    [Key] 
    public int StoreId { get; set; } 
} 

, 생성 된 SQL을 사용하면 삼각형을 수행하기 위해 무엇을 기대입니다 가입 : 당신이 AsExpandable() 포함 할 때

SELECT 
[Project1].[StoreId] AS [StoreId], 
[Project1].[C1] AS [C1], 
[Project1].[StoreId1] AS [StoreId1] 
FROM (SELECT 
    [Limit1].[StoreId] AS [StoreId], 
    [Extent2].[StoreId] AS [StoreId1], 
    CASE WHEN ([Extent2].[StoreId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1] 
    FROM (SELECT TOP (1) [c].[StoreId] AS [StoreId] 
     FROM [dbo].[stores] AS [c]) AS [Limit1] 
    LEFT OUTER JOIN [dbo].[stores] AS [Extent2] ON [Extent2].[StoreId] > [Limit1].[StoreId] 
) AS [Project1] 
ORDER BY [Project1].[StoreId] ASC, [Project1].[C1] ASC 

그러나, 엔티티 프레임 워크는 전체 매장의 표를 끌어 "상수를 생성 할 수 없음"오류로 실패하기 전에 메모리에 저장하십시오.

LINQKit에서 ExpandableQuery의 랩핑을 해제하고 식 구문 분석기에서 중첩 된 하위 쿼리를 평가하는 알려진 해결 방법이 있습니까?

답변

0

시도 할 수있는 한 가지 .AsEnumerable을 사용하고 있습니다. 이렇게하면 오류가 발생하는 SQL로 직접 변환되지 않습니다.

는 자신의 메인에 다음을 시도해보십시오

var table = (IQueryable<Store>)context.Set<Store>(); 
var q = table 
    .AsEnumerable() 
    .Select(t => new {Id = t.StoreId, less = table.Where(tt => tt.StoreId > t.StoreId) }) 
    .Take(1) 
    .ToArray(); 
0

이는 Linqkit 관련이 없습니다. 프리미티브 값만 허용되는 객체를 사용하면 항상 얻게되는 EF 예외입니다.

ttStore 개체라고 생각합니다. 이 오브젝트는 SQL로 변환 될 수 없습니다. 먼저 ID tt.StoreId을 변수에 넣고 쿼리에서 변수를 사용하십시오.