LINQ to Entities 仅支持转换 EDM 原语或枚举类型 - 如何在不调用 ToList() 的情况下进行修复

LINQ to Entities only supports casting EDM primitive or enumeration types - How to fix without ToList() call

我有以下内容:

public IQueryable<T> GetQueryable()
{
    var results = _repository.Table;
    if (typeof(IStoreScopedEntity).IsAssignableFrom(typeof(T)))
    {
        results = results.Where(e => ((IStoreScopedEntity)e).Stores.Select(s => s.Id).Contains(EngineContext.Current.StoreScopeId));
    }
    return results;
}

post 标题中出现错误。我知道我可以在实体上调用 ToList(),以便从数据库中检索它们然后进行转换,但我想避免在不需要时从数据库中取回数据。

有什么方法可以使它工作而无需将数据库中的整个项目列表加载到内存中然后进行选择?

有点棘手,但可行。

首先我们需要一个辅助泛型约束函数。由于从您的定义看来 GetQueryable 函数是通用 class 的一部分,让我们将辅助函数放在单独的 class

public static class StoreScopedEntity
{
    public static Expression<Func<T, bool>> IdPredicate<T>(int id)
        where T : IStoreScopedEntity
    {
        return e => e.Stores.Select(s => s.Id).Contains(id); 
    } 
}

我假设 StoreScopeIdint 类型,但如果不同,您可以将其更改为实际类型。

现在只剩下如何调用那个函数了。有几种方法可以做到这一点,这里我将使用纯反射

public IQueryable<T> GetQueryable()
{
    var results = _repository.Table;
    if (typeof(IStoreScopedEntity).IsAssignableFrom(typeof(T)))
    {
        results = results.Where((Expression<Func<T, bool>>)
            typeof(StoreScopedEntity)
            .GetMethod("IdPredicate", BindingFlags.Public | BindingFlags.Static)
            .MakeGenericMethod(typeof(T))
            .Invoke(null, new object[] { EngineContext.Current.StoreScopeId }));
    }
    return results;
}