【问题标题】:Passing computed values with RIA Services使用 RIA 服务传递计算值
【发布时间】:2011-03-16 20:54:37
【问题描述】:

我正在尝试找出一种方法,让额外的数据与从 RIA 域服务返回的实体一起传递。

例如,假设我想为“订单”显示一个 DataGrid,并为订单中的总项目包括一列。

Order Num.  |  Cust. Name |  *No. of Items Ordered*
4545        |  John       |   4    
1234        |  Mike       |   7

在服务器端,我可以使用 Linq 查询:

var query = 
    from o in entities.Orders
    select new OrderWithItemCount { Order = o, ItemCount = o.Items.Count() };

...这将一次性检索我的订单以及商品数量。

问题是,我无论如何都找不到通过域服务将这些结果传播到 Silverlight 客户端。我想我可以使用标准的 WCF 服务,但这样做有什么乐趣呢?

更新

原来是真正的问题...

我曾一度尝试过 Nissan Fan 和 Florian Lim 指出的“简单方法”。当我尝试它时,我没有得到我的所有数据。 (我还需要在查询中包含客户Person 以获取他们的姓名。)事实证明,我认为RIA 服务的限制实际上是EF 4.0 的限制,因为entities.Orders.Include("Customer") 不会如果您选择不是Order 的新类型,则可以使用。解决方法是在您的 select 语句中显式选择 o.Customer,EF 会自动将选定的 Person 连接到 Order 上的关联属性中。

【问题讨论】:

    标签: silverlight wcf-ria-services


    【解决方案1】:

    简单的方法:

    只需向您的 Order 类添加额外的字段(可以在部分类中完成)并将其填充到您的 DomainService 中。

    复杂但更灵活的方式:

    将 OrderWithItemCount 定义为一个实体(需要有一个 [Key] 属性),然后转移它。

    public class OrderWithItemCount
    {
        [Key]
        public int Id { get; set; }
    
        // You need this, so that the DomainContext on the client can put them back together.
        public int OrderId { get; set; }
    
        [Include]
        [Association("OrderReference", "OrderId", "Id")]
        public Order Order { get; set; }
    
        public int ItemCount { get; set; }
    
        public Person Customer { get; set; }
    }
    
    public IQueryable<OrderWithItemCount> GetOrdersWithItemCount()
    {
        var query = from o in entities.Orders
                    select new OrderWithItemCount
                    {
                        OrderId = o.Id,
                        Order = o,
                        ItemCount = o.Items.Count,
                        Customer = o.Customer, // Makes sure EF also includes the Customer association.
                    };
        return query;
    }
    

    代码中可能存在小错误,因为我目前无法对此进行测试,但我最近实现了类似的东西。

    【讨论】:

    • 我不知道您可以定义一个新实体并以这种方式使用它,谢谢!
    • 我将提交代码编辑,很乐意标记为答案。
    • 创建一个全新的实体来实现这一点当然是一种选择,但您只需将属性添加到由域服务代理创建的部分类或将其添加为LINQ to SQL/EF 的部分类。见下文。
    • @Nissan Fan:同意,事实上这就是我使用真实代码的方式。我将弗洛里安的回答标记为正确只是因为他比您早几分钟发布并且还包含有关创建新实体的信息,这在更复杂的情况下可能会派上用场。您的回答也是正确的,非常感谢!
    【解决方案2】:

    如果您使用 LINQ to SQL 生成域服务,您可以简单地进入 Orders 的部分类并添加一个名为 NumberOfOrders 的属性,该属性返回一个表示计数的 Int。该属性将毫无问题地传递给客户。

    internal sealed class OrderMetadata
            {
    // Metadata classes are not meant to be instantiated.
                private OrderMetadata()
                {
                }
    
                ... (property stubs auto-generated)
            }
    
            public int NumberOfOrders
            {
                get { return this.Items.Count; }
            }
    

    您不能按照上面演示的方式执行此操作的原因是,除了具体的类之外,您无法编组任何东西(匿名类是不行的)。通过将此属性添加到部分类中,它将有效地成为其已发布签名的一部分。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多