Linq where-filter 导致强制转换为基础 class

Linq where-filter causes cast to base class

我有一个具体的通用 IQueryable class:

IQueryable<Person> result = GetAllEmployees(); //returns IQueryable<Employee>

如果我 return result 在 service-call 中 Breeze-Entitytype,一切正常:

breeze.EntityQuery.from("Employees").orderBy("EmployeeID");

一旦我在 service-call 中的 result 中添加一个 where-filter,整个 IQueryable-Object 似乎被铸造到基础 class Person 不再有 属性 EmployeeID:

IQueryable<Person> result = GetAllEmployees(); //returns IQueryable<Employee>
result = result.Where(o => myHashSet.Contains(o.Id));

这会导致以下错误:

Microsoft.Data.OData.ODataException: The query specified in the URI is not valid. Could not find a property named 'EmployeeID' on type 'Person'.

显然,whereIQueryable 包装到一个新的 IQueryable 中,其存储的变量类型。原始 IQueryable 的 ElementType 丢失了.

当您在 where 处中断并检查 result.ElementType 时,您可以看到这一点。一旦您跨过 where,它就会从 Employee 变为 Person

通过以下代码,我们恢复了 ElementType(在 where 之前用 result.ElementType 喂养它):

public static IQueryable<T> ToTypedQueryable<T>(this IEnumerable<T> source, Type theType, bool exact = false) {
    if (source == null) throw new ArgumentNullException("source");

    System.Collections.IList result = (System.Collections.IList)typeof(List<>)
        .MakeGenericType(theType)
        .GetConstructor(Type.EmptyTypes)
        .Invoke(null);

    foreach (var s in source) {
        Type t = s.GetType();
        if (t == theType) {
            result.Add(s);
        } else if (!exact && t.IsSubclassOf(theType)) {
            result.Add(s);
        }
    }

    return (IQueryable<T>)(result.AsQueryable());
}