我正在尝试将 WCF 数据服务中的部分显示及其位置列表投影到自定义类型中。这在 Silverlight 客户端的 WCF 数据服务中是否可行?这里有一些帮助,但它没有显示像简单的字符串那样返回列表。
目前我得到"不支持异常:不支持使用表达式 d.Base.Title 构造或初始化类型为 UserQuery+Info 的实例。如果您能告诉我如何在此语法中扩展位置(我知道Displays.Expand("位置"))或者我需要它,那将是一个奖励。
LINQPad 代码段
var displays = from d in Displays.Where(d => d.Id == 3136)
select new Info
{
Name = d.Base.Title,
};
displays.Dump();
}
public class Info
{
private string name;
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
public IEnumerable<Location> locations;
public IEnumerable<Location> Locations
{
get{ return this.locations;}
set{ this.locations = value;}
}
问题是您实际上是在要求 WCF 服务器构造它不知道的某种类型。由于它无法做到这一点,您必须自己在计算机上进行操作:
Displays
.Where(d => d.Id == 3136)
.AsEnumerable()
.Select(d => new Info { Name = d.Base.Title })
这将在服务器上运行Where()
,但在计算机上运行Select()
。
正如 svick 已经指出的那样,您不能向服务器询问它不理解的类型(至少不使用 OData 即)。但是您仍然只能要求您想要的房产,仅此而已。
由于我没有可用的服务,以下示例在 odata.org 上使用演示服务:
DemoService ctx = new DemoService(new Uri("http://services.odata.org/OData/OData.svc/"));
var q =
ctx.Products
.Where(p => p.ID == 1)
.Select(p =>
new Product
{
Category = new Category
{
Name = p.Category.Name
}
});
var r =
q.AsEnumerable()
.Select(p =>
new
{
CategoryName = p.Category.Name
});
第一个查询 "q" 将在服务器上完整运行(客户端对象的创建除外),它只会获取类别的名称(以及有关所有相关实体的元数据)。它将转换为类似/Products(1)?$expand=类别&$select=类别/名称的 URL。
第二个查询从 AsEnumerable 开始,它有效地执行第一个查询,然后它只是执行到匿名类型的简单转换。这完全在客户端上完成(没有服务器交互)。