LINQKitを共有データ アクセス レイヤーに組み込むことを試みてきましたが、障害にぶつかりました。を使用してネストされたクエリを構築する場合ExpandableQuery
、式パーサーは を正しくラップ解除しExpandableQuery
て有効な SQL クエリを構築することができません。スローされるエラーは次のとおりです。
System.NotSupportedException : 'Store' 型の定数値を作成できません。このコンテキストでは、プリミティブ型または列挙型のみがサポートされています。
次のサンプル プログラムを使用すると、この問題を簡単に再構築でき、AsExpandable()
`table.
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 が生成されます。
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 は、「定数を作成できません」というエラーで失敗する前に、ストア テーブル全体をメモリにプルします。
ExpandableQuery
式パーサー内で入れ子になったサブクエリを強制的にアンラップして評価するように LINQKit に強制する既知の回避策はありますか?