WCF 数据服务 + LINQ 投影到自定义类型

发布于 2024-11-08 07:42:30 字数 825 浏览 2 评论 0原文

我正在尝试将 WCF 数据服务中的显示部分及其位置列表投影到自定义类型中。这在 Silverlight 客户端的 WCF 数据服务中可行吗? 此处有一些帮助,但它不显示获取列表返回以及简单的字符串。

目前我收到“NotSupportedException:不支持使用表达式 d.Base.Title 构造或初始化 UserQuery+Info 类型的实例。”。 如果您能告诉我如何在此语法中扩展位置(我了解 Displays.Expand("Locations"))或者如果我需要它,那就太好了。

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

I'm trying to project parts of a Display and its list of locations from a WCF Data service into a custom type. Is this doable in WCF Data Services in a Silverlight client? There is some help here, but it doesn't show getting a list back as well as simple strings.

Currently I'm getting "NotSupportedException: Constructing or initializing instances of the type UserQuery+Info with the expression d.Base.Title is not supported.".
It would be a bonus if you could tell me how to do Expand on Locations in this syntax (I know about Displays.Expand("Locations")) or if I need it.

LINQPad snippet

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

以歌曲疗慰 2024-11-15 07:42:30

问题在于,您实际上是在要求 WCF 服务器构造一些它不知道的类型。由于它无法执行此操作,因此您必须自己在计算机上执行此操作:

Displays
  .Where(d => d.Id == 3136)
  .AsEnumerable()
  .Select(d => new Info { Name = d.Base.Title })

这将在服务器上运行 Where(),但在您的计算机上运行 Select()

The problem is that you are effectively asking your WCF server to construct some type it has no knowledge about. Since it is unable to do so, you have to it yourself on your computer:

Displays
  .Where(d => d.Id == 3136)
  .AsEnumerable()
  .Select(d => new Info { Name = d.Base.Title })

This will run the Where() on the server, but the Select() on your computer.

小巷里的女流氓 2024-11-15 07:42:30

正如 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”将在服务器上完全运行(创建客户端对象除外),并且它只会获取以下名称:类别(以及有关所有相关实体的元数据)。它将转换为 URL,如 /Products(1)?$expand=Category&$select=Category/Name。

第二个查询以 AsEnumerable 开始,它有效地执行第一个查询,然后仅执行到匿名类型的简单转换。这完全在客户端上完成(没有服务器交互)。

As already noted by svick you can't ask the server for types it doesn't understand (at least not using OData that is). But you can still only ask for properties you want and nothing more.

Since I don't have your service available the below sample uses the demo service on 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
                });

The first query "q" will run compoletely on server (except for creation of the client side objects) and it will only get the Name of the category (and metadata about all the entities in question). It will translate to URL like /Products(1)?$expand=Category&$select=Category/Name.

The second query starts with the AsEnumerable, which effectively executes the first query and then it just performs a simple transform into an anonymous type. This is done completely on the client (no server interaction).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文