在Silverlight中的ADO.Net Data Services中批量加载属性

Pet*_*ert 4 entity-framework silverlight-3.0 wcf-data-services

我在Silverlight 3中使用ADO.Net数据服务(Astoria),我希望在初始加载之后延迟加载实体的属性.但是,当我准备加载它们时,我想将加载请求一起批处理.

// 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>;
Run Code Online (Sandbox Code Playgroud)

我到目前为止:

// 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);
Run Code Online (Sandbox Code Playgroud)

但是,我无法想象如何获取DataServiceRequest对象以将load属性请求传递给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()
});
Run Code Online (Sandbox Code Playgroud)

dmp*_*lla 5

LoadProperty方法不使用dataservice中可用的任何标准类型.但是数据服务足够聪明,可以解决这个问题

LoadProperty(person, "Gender")
Run Code Online (Sandbox Code Playgroud)

是相同的

person.Gender = (from g in ent.Person
                 where g.ID == person.ID
                 select g.Gender).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

生成的Uri是一样的.

http://localhost/WebDataService.svc/Person(1)/Gender
Run Code Online (Sandbox Code Playgroud)

因此,如果要在批处理查询中调用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));
    }
}
Run Code Online (Sandbox Code Playgroud)

所以现在你可以做到这一点.

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

唯一剩下的就是这只会告诉你它不会做的事情是将返回值分配给实体属性,你必须自己在BatchCallback上做.

无论如何,彼得希望这可以帮助你实现你想要的.

如有任何需要,请告诉我

问候

丹尼尔