C#:默认情况下使System.Data.Services.Client.DataServiceQuery异步

时间:2018-07-24 20:51:45

标签: c# android xamarin mono odata

Mono.Android要求我执行异步查询。我可以这样:

DataServiceQuery<T> dataServiceQuery = query as DataServiceQuery<T>;
return (new TaskFactory<IEnumerable<T>>()).FromAsync(dataServiceQuery.BeginExecute(null, null), asyncResult => dataServiceQuery.EndExecute(asyncResult)).Result;

问题是我不想每次查询时都调用此方法,因为这会迫使正在使用我的库的用户调用该方法,否则Mono将崩溃,因此我想使用DataServiceQuery默认情况下执行此操作。我可以通过重写DataServiceQuery的GetEnumerator()函数来实现此目的,但是它的构造函数是私有的,因此不允许这样做。我猜想剩下的唯一选择是用我的更改重新编译System.Data.Services.Client.dll。也许DataServiceContext有一个窍门,但老实说我没有选择。

感谢您的帮助, 格言

1 个答案:

答案 0 :(得分:0)

不可能自动执行此操作,但是可以通过创建一个名为SelectAsync的新Select函数来使语句更好。

事实上,这也解决了OData和LINQ的问题,因为您必须将Selects包装为匿名类型,现在您可以在查询后调用Select(由于查询整个类花费的时间更长,但这对我来说不是问题)。

这是SelectAsync扩展方法的代码:

public static IEnumerable<T> SelectAsync<T>(this IQueryable<T> queryable)
{
    return queryable.SelectAsync(x => x);
}

public static IEnumerable<TResult> SelectAsync<T, TResult>(this IQueryable<T> queryable, Function<T, TResult> selector)
{
    var dataServiceQuery = queryable as DataServiceQuery<T>;
    return Task.Run(async () => (await (new TaskFactory<IEnumerable<T>>()).FromAsync(dataServiceQuery.BeginExecute, dataServiceQuery. EndExecute, null)).Select(selector)).Result;
}

在Mono.Android中使用LINQ执行查询现在更加直观。

var itemNames = Items.Where(item => item.ID == 0).Select(item => item.Name);
var goodCars = Cars.Where(car => car.Fuel >= 0.5);

翻译为:

var itemNames = Items.Where(item => item.ID == 0).SelectAsync(item => item.Name);
var goodCars = Cars.Where(car => car.Fuel >= 0.5).SelectAsync();

据我所知,这是可以得到的,因为Mono.Android当前不完全支持System.Data.Services。这是一个不错且直观的解决方法。

来源: