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

时间:2015-12-24 15:54:49

标签: c# entity-framework linq linq-to-sql

我有以下内容:

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

我在帖子标题中收到错误。我知道我可以在实体上调用ToList(),以便从数据库中检索它们然后进行转换,但是当我不需要时,我想避免从数据库中恢复数据。

如果没有将数据库中的整个项目列表加载到内存中然后选择,我有什么办法可以让它工作吗?

1 个答案:

答案 0 :(得分:1)

有点棘手,但可行。

首先我们需要一个辅助通用约束函数。由于你的定义看起来GetQueryable函数是泛型类的一部分,所以让把辅助函数放在一个单独的类中

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

我认为StoreScopeId的类型为int,但如果它不同,您可以将其更改为实际类型。

现在唯一剩下的就是如何调用该函数。有几种方法可以做到这一点,在这里我将使用纯反射

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