2013-08-20 13 views
12

Próbowałem włączyć LINQKit do warstwy dostępu do udostępnionych danych, jednak trafiłem na blokadę drogi. Podczas konstruowania zapytania zagnieżdżonego przy użyciu parametru ExpandableQuery parser wyrażeń nie może poprawnie oddzielić obiektu ExpandableQuery i utworzyć poprawnego zapytania SQL. Wystąpił błąd:LINQKit: zagnieżdżanie ExpandableQuery w LINQ do encji

System.NotSupportedException: Nie można utworzyć stałej wartości typu "Store". W tym kontekście obsługiwane są tylko typy pierwotne lub typy wyliczeniowe.

Za pomocą poniższego przykładowego programu możemy łatwo zrekonstruować ten problem i jest wyraźnie odizolowany od wywołania AsExpandable() w tabeli.

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; } 
} 

Po usunięciu połączenia AsExpandable(), SQL generowany jest to, czego można oczekiwać, aby wykonać trójkątne dołączyć:

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 

Jeśli jednak zawierać AsExpandable(), Entity Framework ciągnie całą przechowuje tabelę do pamięci, przed niepowodzeniem z błędem "Nie można utworzyć stałej".

Czy są jakieś znane sposoby, aby zmusić LINQKit do rozwinięcia ExpandableQuery i oceny zagnieżdżonego podkwerendy w parserze wyrażeń?

Odpowiedz

0

Jedną z rzeczy, które można wypróbować, jest użycie .AsEnumerable. Zapobiegnie to bezpośredniemu tłumaczeniu do SQL, z którego pochodzi błąd.

Spróbuj wykonać następujące czynności w głównym:

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

ta nie jest związana z Linqkit. Jest to wyjątek EF, który zawsze występuje, gdy używasz obiektu, w którym dozwolona jest tylko wartość pierwotna.

Myślę, że tt jest obiektem Store. Tego obiektu nie można przekonwertować na SQL. Najpierw umieść ID tt.StoreId w zmiennej i użyj zmiennej w zapytaniu.

Powiązane problemy