Загрузить свойство в пакете в ADO.Net Data Services в Silverlight - PullRequest
4 голосов
/ 15 декабря 2009

Я использую службы данных ADO.Net (Astoria) в Silverlight 3 и хочу отложить загрузку свойств объекта до окончания начальной загрузки. Тем не менее, когда я буду готов их загрузить, я бы хотел объединить запросы на загрузку.

// this is what I want to avoid
var c = (from c in ctx.Customers.Expand("Address,Phone,Email")
         where c.Id = 12
         select c).Take(1) as DataServiceQuery<Customer>;

Я получил это далеко:

// I can do this instead
var c = (from c in ctx.Customers // .Expand("Address,Phone,Email")
         where c.Id = 12
         select c).Take(1) as DataServiceQuery<Customer>;
c.BeginExecute(CustomerCallback, objState);

...

// Later, when I want properties, I need to do this
ctx.BeginLoadProperty(c, "Address", AddressCallback, objState);
ctx.BeginLoadProperty(c, "Phone", PhoneCallback, objState);
ctx.BeginLoadProperty(c, "Email", EmailCallback, objState);

Однако я не могу понять, как получить объект DataServiceRequest для запроса свойства загрузки для передачи в BeginExecuteBatch. Можно ли выполнить эти запросы (и, возможно, другие, которые не связаны с загрузкой свойств клиента) в одном пакете, получив DataServiceQuery?

Примерно так:

// c is the customer from the above load
ctx.BeginExecuteBatch(BatchCallback, objState, new []{
    ctx.GetLoadQuery(c, "Address"),
    ctx.GetLoadQuery(c, "Phone"),
    ctx.GetLoadQuery(c, "Email"),
    GetOtherNonPropertyQuery()
});

1 Ответ

5 голосов
/ 16 декабря 2009

Метод LoadProperty не использует какие-либо стандартные типы, доступные вам в dataservice. Однако служба данных достаточно умна, чтобы понять, что

LoadProperty(person, "Gender")

совпадает с

person.Gender = (from g in ent.Person
                 where g.ID == person.ID
                 select g.Gender).FirstOrDefault();

Сгенерированный Uri такой же.

http://localhost/WebDataService.svc/Person(1)/Gender

Так что, если вы хотите вызвать LoadProperty в пакетном запросе, вы можете довольно легко сгенерировать Uri. Смотри ниже.

public static class DataServiceContextExtensions
{
    public static Uri GetLoadPropertyUri(this DataServiceContext context, object entity, string property)
    {
        Uri entityUri = null;
        if(context.TryGetUri(entity, out entityUri))
        {
            return new Uri(entityUri.AbsoluteUri + "/" + property);
        }
        throw new DataServiceClientException("Entity Uri not found.");
    }

    public static DataServiceRequest<T> GetLoadPropertyRequest<T>(this DataServiceContext context, object entity, string property)
    {
        return new DataServiceRequest<T>(context.GetLoadPropertyUri(entity, property));
    }
}

Итак, теперь вы можете сделать это.

ctx.BeginExecuteBatch(BatchCallback, objState, new []{
    ctx.GetLoadPropertyRequest<Address>(c, "Address"),
    ctx.GetLoadPropertyRequest<Phone>(c, "Phone"),
    ctx.GetLoadPropertyRequest<Email>(c, "Email"),
    GetOtherNonPropertyQuery()
});

Осталось только то, что это вернет вам только тот объект (объекты), что он не сделает, это присвоит возвращаемое значение (я) свойству объекта, что вам придется сделать это самостоятельно на вашем BatchCallback.

Во всяком случае, Питер Хоуп, это поможет вам в том, что вы хотите.

Если вам что-то понадобится, дайте мне знать

Привет

Daniel

...