Передача вычисленных значений с помощью RIA Services - PullRequest
0 голосов
/ 16 марта 2011

Я пытаюсь выяснить, как получить дополнительные данные для передачи с сущностями, возвращенными из службы домена 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, но что в этом хорошего?

Обновление

Что оказалось актуальной проблемой ...

В какой-то момент я уже попробовал " Простой способ ", на который указывают Ниссан Фан и Флориан Лим. Когда я попробовал это, я не получил все свои данные. (Мне также нужно включить клиента Person в запрос, чтобы получить его имя.) Оказывается, что то, что я считал ограничением RIA Services, на самом деле было ограничением EF 4.0, в этом высказывании entities.Orders.Include("Customer") не будет работать, если вы выбираете новый тип, который не является Order. Обходной путь состоит в том, чтобы явно выбрать o.Customer в вашем операторе выбора, и EF автоматически подключит выбранного персонажа к ассоциированному свойству в Order.

Ответы [ 2 ]

1 голос
/ 17 марта 2011

Если вы используете 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; }
        }

Причина, по которой вы не можете сделать это так, как вы продемонстрировали выше, заключается в том, что вы не можете проводить маршалинг по чему-либо, кроме конкретных классов (анонимные классы запрещены). При добавлении этого свойства в частичный класс оно фактически станет частью его опубликованной подписи.

1 голос
/ 17 марта 2011

Простой способ:

Просто добавьте дополнительные поля в ваш класс 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;
}

Могут быть незначительные ошибкив коде, так как я не могу проверить это в данный момент, но недавно я реализовал нечто подобное.

...