我一直試圖將LINQKit併入共享數據訪問層,但是,我遇到了障礙。在使用ExpandableQuery
構造嵌套查詢時,表達式解析器無法正確解開ExpandableQuery
並構造有效的SQL查詢。拋出的錯誤如下:LINQKit:將LINQ中的ExpandableQuery嵌套到實體
System.NotSupportedException:無法創建類型爲'Store'的常量值。只有原始類型或枚舉類型在此上下文中受支持。
通過下面的示例程序,我們可以很容易地重建這個問題,並且它明確地與表'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; }
}
當您刪除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()
,實體框架拉動整個賣場表進入內存之前,無法創建「無法創建常量」錯誤。
是否有任何已知的解決方法來強制LINQKit解開ExpandableQuery
並評估表達式解析器中的嵌套子查詢?