我不确定如何表达我想要实现的目标,而不会显示一些伪代码 -
假设定义了以下DTO:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
我们定义了两个不同的自定义IQueryable<T>
类:
public class InnerQueryable<T> : IQueryable<T>
{
// ...
}
public class OuterQueryable<T> : IQueryable<T>
{
public OuterQueryable(IQueryable<T> inner)
{
// Assign `inner` to a local variable to be used in `IQueryable<T>` impl.
// ...
}
// ...
}
注意:OuterQueryable<T>
旨在通过包装来扩展任何其他IQueryable<T>
类型的行为。
一种相当天真的扩展方法,可以简单地创建OuterQueryable<T>
实现:
public static IQueryable<T> ToOuterQueryable<T>(this IQueryable<T> inner /*, ... */)
{
// Assume `OuterQueryable<T>` has a constructor that takes another `IQueryable<T>`.
return new OuterQueryable<T>(inner /*, ... */);
}
给定如下所示的表达式,InnerQueryable<T>
实例是否有任何方法可以在查询被OuterQueryable<T>
包装后找出选择了哪些特定属性?
InnerQueryContext.AsQueryable<Person>().Where(p => p.Age > 30)
.ToOuterQueryable().Select(p => new
{
p.FirstName,
p.LastName
};
无论如何,InnerQueryable<T>
知道构建的查询
OuterQueryable<T>
仅返回Person.FirstName
和Person.LastName
?
如果有助于显示上下文,我有一个返回内部实体的WCF数据服务,但我需要能够知道从服务返回内部实体的哪些特定成员。 WCF DS在这种情况下定义了OuterContext<T>
,我还没有找到一种方法来拦截投影后的响应,告诉我我在寻找什么。
欢迎任何想法。
更新:什么是InnerQueryable<T>
和OuterQueryable<T>
?
如果您不熟悉WCF数据服务的体系结构,那么答案是相当复杂的,但是在这里:
在WCF数据服务中,服务将IQueryable<T>
属性公开给DataServiceProvider实现(即EntityFrameworkDataServiceProvider
,ReflectionDataServiceProvider
或实现必要接口的自定义DataServiceProvider
实现(或多个))。
这些核心IQueryable<T>
属性充当通过服务公开的资源的基础,并且构建在使用LINQ查询的可组合性质的基础上。使用上面的Person
实体的简单示例如下所示:
public class SimpleContext
{
public IQueryable<Person> People
{
get
{
return new[] {
new Person { FirstName = "George", LastName = "Jetson", Age = 43 },
new Person { FirstName = "Elroy", LastName = "Jetson", Age = 7 }
}.AsQueryable();
}
}
}
这个SimpleContext
将由简单的数据服务实现引用:
public class SimpleDataService : DataService<SimpleContext>
{
// InitializeService method and others...
}
现在,当我查询传递投影的数据服务时:
http://localhost/SimpleDataService/People()?$select=FirstName,LastName
该框架将从IQueryable<Person>
返回SimpleDataContext.People
并将其传递给内部IQueryProvider
/ IQueryable
实现,该实现了解如何从查询字符串生成表达式树参数,然后使用IQueryable<Person>
作为其来源撰写另一个查询。
从概念上讲,我上面的原始问题描述了如何复制行为,而不必担心所有WCF数据服务的内容。
答案 0 :(得分:2)
我仍然不太明白为什么WCF DS需要OuterQueryable
。它需要做的是解析查询,然后根据它调用InnerQueryable
。
如果你的InnerQueryable
周围确实存在某种包装,那么完全由该包装器来决定你的包装器可查询的内容。
考虑包装器的两个简单实现:如果包装器只是将每个方法调用转发给包装对象,那么您将能够直接看到所有内容。另一方面,如果包装器根本不做任何事情,那么根本无法观察任何事情。