Azure Mobile Services C# won't return child entities

我只是一个虾纸丫 提交于 2019-11-27 18:14:38

问题


I'm really hitting a brick wall with the new C# based Azure Mobile Services, and it's really simple too :( I can't for the life of me get the query operation to return child property values. I have the todo item of the default project modified like this:

public class TodoItem : EntityData
{
    public TodoItem()
    {
        this.Numbers = new Collection<TodoItemNumbers>(new List<TodoItemNumbers>
        {
            new TodoItemNumbers{Value = 1},
            new TodoItemNumbers{Value = 2},
            new TodoItemNumbers{Value = 3},
            new TodoItemNumbers{Value = 4},
            new TodoItemNumbers{Value = 5},
        });
    }
    public virtual ICollection<TodoItemNumbers> Numbers { get; set; }
    public string Text { get; set; }
    public bool Complete { get; set; }
}

And then I have the TodoItemNumbers class defined like this:

public class TodoItemNumbers : EntityData
{
    private int _value;

    public int Value
    {
        get { return _value; }
        set
        {
            _value = value;
            Id = value.ToString();
        }
    }

    public string TodoItemId { get; set; }
}

In the TodoItemController I've overridden the Query method like this

protected override IQueryable<TodoItem> Query()
{
    return base.Query().Include(x => x.Numbers);
}

None of this will return the Numbers property when I make a request with Fiddler. In a moment of madness I also modified the Initialize method of the controller to include this:

protected override void Initialize(HttpControllerContext controllerContext)
{
    base.Initialize(controllerContext);
    myContext context = new myContext();
    context.Configuration.LazyLoadingEnabled = false;
    context.Configuration.ProxyCreationEnabled = false;
    DomainManager = new EntityDomainManager<TodoItem>(context, Request, Services);
}

Note the lazy loading and proxy creation have both been turned off. Does anyone know how to beat this simple scenario? I'm not feeling the good vibes on this one.

Update So as I answered below I was able to get the service to return the data by adding in the $expand to the query. Now however I'm really stuck on getting the client to add that parameter to the request. It's always just returning the base data.

    var data = await App.MobileService.GetTable<TodoItem>()
        .ToListAsync();

won't return the child properties, and there isn't an Include option on the result type


回答1:


My mistake was not really putting the OData part into the equation. As soon as I queried

http://localhost:51025/tables/todoitem?$expand=Numbers

instead of

http://localhost:51025/tables/todoitem

It magically appeared. Now how do I get that to come across in the client API...? Update I managed it on the client side with this code

var json =
                    await
                        App.MobileService.GetTable("TodoItem")
                            .ReadAsync("$expand=Numbers");
JsonConvert.DeserializeObject<TodoItem>(json.First.ToString());

But there has to be a better way




回答2:


It is also possible to achieve it by adding a handler on the client:

var client = new MobileServiceClient("http://xxxxxx/", null, new ODataParameterHandler());

public class ODataParameterHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        UriBuilder builder = new UriBuilder(request.RequestUri);

        builder.Query = builder.Query
            .Replace("expand", "$expand")
            .TrimStart('?');

        request.RequestUri = builder.Uri;

        return await base.SendAsync(request, cancellationToken);
    }
}

Usage:

var test = await client.GetTable<TodoItem>()
    .WithParameters(new Dictionary<string, string> { { "expand", "Something" } })
    .ToListAsync();



回答3:


Instead of overriding the Query method, have the GetAllTodoItems method look like this:

public IList<TodoItem> GetAllTodoItems()
{
    return context.TodoItems.Include( "Numbers" ).ToList();
}

This is an alternative to the $expand hack. I discovered it while exploring Azure App Service mobile apps for myself. Chaining on an Include call alone, as you originally attempted, would make more sense to me if it worked. Next, I'd like to figure out why that doesn't work.




回答4:


I thought it was .Include(x => x.Numbers) after the gettable




回答5:


I had the same issue & using expand did help. Then a @carlosfigueira suggested a better way of handling this scenario here

How do we load related objects (Eager Loading) in Dot Net based Azure Mobile Service?

Please have a look. So far the best approach to tackle this issue. Supreet



来源:https://stackoverflow.com/questions/23316910/azure-mobile-services-c-sharp-wont-return-child-entities

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!