我一直试图将LINQKit合并到共享数据访问层中,但是遇到了障碍。使用ExpandableQuery构造嵌套查询时,表达式解析器无法正确展开ExpandableQuery并构造有效的SQL查询。引发的错误为:


System.NotSupportedException:无法创建类型为'Store'的常量值。在此上下文中仅支持原始类型或枚举类型。


通过以下示例程序,我们可以轻松地重建此问题,并且显然可以将其与`table上的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并评估表达式解析器中的嵌套子查询?

最佳答案

您可以尝试的一件事是使用.AsEnumerable。这将阻止直接转换为SQL,这就是您的错误出处。

在您的Main中尝试以下操作:

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();

关于linq - LINQKit:在LINQ中将ExpandableQuery嵌套到实体,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18346014/

10-12 17:05