2013-08-20 26 views
12

LINQKitを共有データアクセスレイヤに組み込みようとしていましたが、私はロードブロッキングを打ちました。 ExpandableQueryを使用してネストされたクエリを作成すると、式パーサーはExpandableQueryを正しくアンラップして有効なSQLクエリを構築できません。スローされたエラーは読み取ります。LINQKit:エンティティへのLINQでのExpandableQueryのネスト

System.NotSupportedException: 'Store'型の定数値を作成できません。このコンテキストでは、プリミティブ型または列挙型のみがサポートされています。

次のサンプルプログラムでは、この問題を簡単に再構築することができます。これは明らかに `tableの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 

、あなたがAsExpandable()を含む場合、Entity Frameworkのは、全体のstoresテーブルを引く:

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

あなたがAsExpandable()呼び出しを削除すると、生成されたSQLは、あなたが参加三角形を行うことを期待するものです「定数を作成できません」というエラーが表示される前にメモリに保存してください。

LINQKitにExpandableQueryのラップを解除させ、式パーサー内のネストされたサブクエリを評価するための既知の回避策はありますか?

答えて

0

試してみることの1つは、.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を変数に入れ、その変数をクエリに使用します。

関連する問題