Simple.OData.Client有一个类型化和动态(和基本)语法。
我喜欢打字,但我不想把我所有的类型都建出来。最后,我真的只需要两种左右的类型,在我得到的结果。
但是我的查询需要更多的类型来正确地过滤结果。
所以我想使用动态语法。但我想把结果加到我的课堂上。
我可以很容易地手动完成这个任务,但在编写每个查询的所有转换代码之前,我想先看看Simple.OData.Client是否支持这一点。
下面是一些运行时没有错误的动态语法代码:
client.For(x.Client).Top(10).Select(x.ClientId, x.Name).FindEntriesAsync();下面是我希望能够工作的一个例子(选择一个新的客户端对象)
client.For(x.Client).Top(10).Select(new Client(x.ClientId, x.Name)).FindEntriesAsync();但是这种投影是不支持的(我得到了一个“有一些无效的参数”错误)。
在使用Simple.OData.Client?的动态语法时,是否有一种方法支持将投影投影到现有的类中
发布于 2019-09-17 18:25:28
编辑:下面的代码工作。但表演太糟糕了。我决定放弃它,为我所需要的每一种类型编写手写的映射器。
这就是我想出来的:
dynamic results = oDataClient.For(x.Client).Select(x.ClientId, x.Name).FindEntriesAsync().Result;
var listOfClients = SimpleODataToList<Client>(results);
public List<T> SimpleODataToList<T>(dynamic sourceObjects) where T : new()
{
List<T> targetList = new List<T>();
foreach (var sourceObject in sourceObjects)
{
// This is a dictionary with keys (properties) and values. But no
// matter what sourceObject is passed in, the values will always be
// the values of the first entry in the sourceObjects list.
var sourceProperties = ((System.Collections.Generic.IDictionary<string, object>)sourceObject);
var targetProperties = typeof(Client).GetProperties().Where(prop => prop.CanWrite);
var targetObject = new T();
foreach (var targetProperty in targetProperties)
{
if (sourceProperties.ContainsKey(targetProperty.Name))
{
var sourceValue = GetProperty(sourceObject, targetProperty.Name);
targetProperty.SetValue(targetObject, sourceValue, null);
}
}
targetList.Add(targetObject);
}
return targetList;
}
public static object GetProperty(object o, string member)
{
if (o == null) throw new ArgumentNullException("o");
if (member == null) throw new ArgumentNullException("member");
Type scope = o.GetType();
IDynamicMetaObjectProvider provider = o as IDynamicMetaObjectProvider;
if (provider != null)
{
ParameterExpression param = Expression.Parameter(typeof(object));
DynamicMetaObject mobj = provider.GetMetaObject(param);
GetMemberBinder binder = (GetMemberBinder)Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, member, scope, new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(0, null) });
DynamicMetaObject ret = mobj.BindGetMember(binder);
BlockExpression final = Expression.Block(
Expression.Label(CallSiteBinder.UpdateLabel),
ret.Expression
);
LambdaExpression lambda = Expression.Lambda(final, param);
Delegate del = lambda.Compile();
return del.DynamicInvoke(o);
}
else
{
return o.GetType().GetProperty(member, BindingFlags.Public | BindingFlags.Instance).GetValue(o, null);
}
}这变得更加困难,因为普通的强制转换以及对返回的动态对象的转换只会一次又一次地给出列表中的第一个对象。GetProperty方法可以绕过这一限制。
https://stackoverflow.com/questions/57965353
复制相似问题