gpt4 book ai didi

Azure 移动服务 Lookupasync 加载导航属性

转载 作者:行者123 更新时间:2023-12-01 09:36:01 24 4
gpt4 key购买 nike

我在服务端有一个 Place data_object,其中包含导航属性Roads:

public class Place : EntityData
{
...
public List<Road> Roads { get; set; }
}

现在在客户端,我想使用其 id 获取 Place 对象,但导航属性 Roads 无法加载。我可以添加任何参数或属性来使其工作吗?

我的代码:

var roadList = await App.MobileService.GetTable<Place>()
.LookupAsync(placeId);

最佳答案

由于在 EF 中加载导航属性需要在数据库中进行 JOIN 操作(这很昂贵),因此正如您所注意到的,默认情况下不会加载它们。如果您希望加载它们,您需要通过发送 $expand=<propertyName> 向客户端请求。查询字符串参数。

有两种实现方式:在服务器中和在客户端中。如果您想在服务器中执行此操作,您可以实现一个操作过滤器,它将修改客户端请求并添加该查询字符串参数。您可以使用下面的过滤器来做到这一点:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
class ExpandPropertyAttribute : ActionFilterAttribute
{
string propertyName;

public ExpandPropertyAttribute(string propertyName)
{
this.propertyName = propertyName;
}

public override void OnActionExecuting(HttpActionContext actionContext)
{
base.OnActionExecuting(actionContext);
var uriBuilder = new UriBuilder(actionContext.Request.RequestUri);
var queryParams = uriBuilder.Query.TrimStart('?').Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries).ToList();
int expandIndex = -1;
for (var i = 0; i < queryParams.Count; i++)
{
if (queryParams[i].StartsWith("$expand", StringComparison.Ordinal))
{
expandIndex = i;
break;
}
}

if (expandIndex < 0)
{
queryParams.Add("$expand=" + this.propertyName);
}
else
{
queryParams[expandIndex] = queryParams[expandIndex] + "," + propertyName;
}

uriBuilder.Query = string.Join("&", queryParams);
actionContext.Request.RequestUri = uriBuilder.Uri;
}
}

然后您可以使用该属性装饰您的方法:

[ExpandProperty("Roads")]
public SingleItem<Place> GetPlace(string id) {
return base.Lookup(id);
}

实现此目的的另一种方法是更改​​客户端代码以发送该 header 。目前的过载为LookupAsync接受额外查询字符串参数的(以及所有其他 CRUD 操作)不能用于添加 $expand参数(或任何其他 $-* 参数),因此您需要为此使用处理程序。例如,这是一个这样的处理程序:

class MyExpandPropertyHandler : DelegatingHandler
{
string tableName
string propertyName;

public MyExpandPropertyHandler(string tableName, string propertyName)
{
this.tableName = tableName;
this.propertyName = propertyName;
}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (request.Method.Method == HttpMethod.Get.Method &&
request.RequestUri.PathAndQuery.StartsWith("/tables/" + tableName, StringComparison.OrdinalIgnoreCase))
{
UriBuilder builder = new UriBuilder(request.RequestUri);
string query = builder.Query;
if (!query.Contains("$expand"))
{
if (string.IsNullOrEmpty(query))
{
query = "";
}
else
{
query = query + "&";
}

query = query + "$expand=" + propertyName;
builder.Query = query.TrimStart('?');
request.RequestUri = builder.Uri;
}
}

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

您可以通过创建 MobileServiceClient 的新实例来使用处理程序:

var expandedClient = new MobileServiceClient(
App.MobileService.ApplicationUrl,
App.MobileService.ApplicationKey,
new MyExpandPropertyHandler("Place", "Roads"));
var roadList = await App.MobileService.GetTable<Place>()
.LookupAsync(placeId);

关于Azure 移动服务 Lookupasync 加载导航属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25690779/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com