我有下一个LINQ查询,它模拟了两个数据表上的完全外部联接
{"r1(0)", "r2(0)", "r1(1)", "r2(1)", "math.abs(cdec(r1(2))-cdec(r1(3)))", "math.abs(cdec(r2(2))-cdec(r2(3)))"}
adn返回Object [] []。
我的愿望是将{"math.abs(cdec(r1(2))-cdec(r1(3)))", "math.abs(cdec(r2(2))-cdec(r2(3)))"}
传递到LINQ查询模式的WHERE子句中。
在传递(From r1 As datarow In dt1
From r2 As datarow In dt2
Where
math.abs(CDec(r1(2))-CDec(r1(3))).Equals( math.abs(CDec(r2(2))-CDec(r2(3))) )
Select r1.ItemArray.Concat(r2.itemarray).ToArray).toarray
的情况下,LINQ查询应如下所示:
"r1(0), r2(0); r1(1), r2(1); math.abs(cdec(r1(2))-cdec(r1(3))), math.abs(cdec(r2(2))-cdec(r2(3)))"
我可以选择传递字符串dt1.AsEnumerable.AsQueryable
.Join(
dt2.AsEnumerable,
"new(get_Item(0) as Column0, get_Item(1) as Column1)",
"new(get_Item(0) as Column0, get_Item(1) as Column1)",
"new(outer.get_Item(4) as Column4, inner.get_Item(4) as Column4)"
)
。
非常感谢您的帮助。
巨大更新
尝试使用此表达式(基于System.Linq.Dynamic.Core)
in_dt1.AsEnumerable.AsQueryable
.Join(
in_dt2.AsEnumerable,
"new(math.abs(cdec(get_Item(2) as Column2)-cdec(get_Item(3) as Column3)) as A)",
"new(math.abs(cdec(get_Item(2) as Column2)-cdec(get_Item(3) as Column3)) as A)",
"new(outer.get_Item(4) as Column4, inner.get_Item(4) as Column4)"
)
抛出“发现模糊匹配”。
也将我的表情从以前的改变为
{{1}}
引发“')'或','预期”异常。
答案 0 :(得分:0)
如果您纠正了类型错误并使用了正确的功能,则可以使其正常工作:
var ans = ((IQueryable)dt1.AsEnumerable().AsQueryable())
.Join(dt2.AsEnumerable(),
"new(get_Item(0) as c0, get_Item(1) as c1, math.abs(Convert.ToDecimal(get_Item(2))-Convert.ToDecimal(get_Item(3))) as c2)",
"new(get_Item(0) as c0, get_Item(1) as c1, math.abs(Convert.ToDecimal(get_Item(2))-Convert.ToDecimal(get_Item(3))) as c2)",
"new(outer.get_Item(4) as Column0, inner.get_Item(4) as Column1)"
);
动态LINQ不支持创建数组,但是使用Reflection可以将对象转换为数组-但是,我不确定我会推荐这样做。
使用以下扩展方法将任何对象转换为提供的类型(必须可转换)的数组:
public static class TypeExt {
public static List<MemberInfo> GetPropertiesOrFields(this Type t, BindingFlags bf = BindingFlags.Public | BindingFlags.Instance) =>
t.GetMembers(bf).Where(mi => mi.MemberType == MemberTypes.Field || mi.MemberType == MemberTypes.Property).ToList();
}
public static class MemberInfoExt {
public static object GetValue(this MemberInfo member, object srcObject) {
switch (member) {
case FieldInfo mfi:
return mfi.GetValue(srcObject);
case PropertyInfo mpi:
return mpi.GetValue(srcObject);
case MethodInfo mi:
return mi.Invoke(srcObject, null);
default:
throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo or MethodInfo", nameof(member));
}
}
}
public static class ObjectExt {
public static T[] ToArray<T>(this object obj, BindingFlags bf = BindingFlags.Public | BindingFlags.Instance) {
List<T> ans;
if (obj is IDictionary<string, object> id)
ans = id.Values.Select(v => (T)v).ToList();
else {
ans = new List<T>();
foreach (var prop in obj.GetType().GetPropertiesOrFields(bf)) {
try {
ans.Add((T)prop.GetValue(obj));
}
catch (Exception) {
// ignore inaccessible properties
}
}
}
return ans.ToArray();
}
}
您可以将创建的匿名对象转换为string[]
:
var ans2 = ans.AsEnumerable()
.Select(v => ((object)v).ToArray<string>())
.ToList();