我想将Linq查询插入到数据表中,但出现以下错误 IEnumberable“ <<”匿名类型无法转换为IEnumerable。为什么我会收到此错误以及如何解决?
IEnumerable<DataRow> sql = from dr in Csvdaten.AsEnumerable()
join dr2 in Csvimportdaten.AsEnumerable() on dr.Field<string>("customer_id_spam") equals dr2.Field<string>("customer_id_spam")
select new
{
CAMPAIGN_ID = Convert.ToInt32(dr2["CAMPAIGN_ID"]),
MEDIUM_CODE = Convert.ToString(dr2["MEDIUM_CODE"])
};
DataTable dt = sql.CopyToDataTable();
答案 0 :(得分:-1)
如果您不关心匹配特定的DataTable
,而只是想即时生成它们,而又不太担心反射引起的性能损失,则可以使用这些扩展。
首先,一些帮助程序扩展使使用带有属性或字段的反射更加容易:
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 Type GetMemberType(this MemberInfo member) {
switch (member) {
case FieldInfo mfi:
return mfi.FieldType;
case PropertyInfo mpi:
return mpi.PropertyType;
case EventInfo mei:
return mei.EventHandlerType;
default:
throw new ArgumentException("MemberInfo must be if type FieldInfo, PropertyInfo or EventInfo", nameof(member));
}
}
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);
default:
throw new ArgumentException("MemberInfo must be of type FieldInfo or PropertyInfo", nameof(member));
}
}
public static T GetValue<T>(this MemberInfo member, object srcObject) => (T)member.GetValue(srcObject);
}
然后是一个IEnumerable<T>
扩展名,用于将IEnumerable<anonymous>
转换为DataTable
:
public static class IEnumerableExt {
public static DataTable ToDataTable<T>(this IEnumerable<T> rows) {
var dt = new DataTable();
if (rows.Any()) {
var rowType = typeof(T);
var memberInfos = rowType.GetPropertiesOrFields();
foreach (var info in memberInfos)
dt.Columns.Add(new DataColumn(info.Name, info.GetMemberType()));
foreach (var r in rows)
dt.Rows.Add(memberInfos.Select(i => i.GetValue(r)).ToArray());
}
return dt;
}
}