我有这样的linq到dataTable查询:
`var ShowResult = from r in Result.AsEnumerable()
where Convert.ToInt32(r.Field<double>("ASLVAM") / r.Field<double>("GEST")) > 60
orderby Convert.ToInt32(r.Field<double>("ASLVAM") / r.Field<double>("GEST")) descending
select new
{
pascode = r.Field<string>("PAS_CODE"),
melli = r.Field<string>("CODEMELI"),
name = r.Field<string>("NAM"),
family = r.Field<string>("FAMILY"),
bycode = r.Field<string>("BAYGANI"),
jancode = r.Field<string>("CODEJANBAZ"),
darsad = r.Field<int>("DARSAD"),
ostan = r.Field<string>("OSTAN_N"),
vacode = r.Field<string>("VA_CODE"),
moin = r.Field<string>("VA_MOIN"),
onvan = r.Field<string>("TAFZILI"),
aslvam = r.Field<double>("ASLVAM"),
gest = r.Field<double>("GEST"),
//tededGestKol = Convert.ToInt32(r.Field<double>("ASLVAM") / r.Field<double>("GEST")),
mandeVam = r.Field<double>("MANDE_VAM"),
dPardakht = r.Field<string>("DATE_P")
};`<code>
我添加了参考System.Data.DataSetExtentions来使用CopyToDataTable()方法在dataGrid视图中显示我的查询结果但这个方法没有添加到我的Inellisence, 我也使用MSDN Sample来使用这个方法,但这次我遇到了这个错误: “指定演员表无效” 请帮助我,我该怎么做才能克服这个问题?
答案 0 :(得分:4)
CopyToDataTable()仅在查询返回IEnumerable&lt;'DataRow&gt;时有效。在您的查询中,您将返回匿名类型。匿名类型不携带CopyToDataTable()的扩展方法。您可以像这样选择整行,假设Result是DataTable。然后创建您的匿名类型。
public static void Start()
{
DataTable Result = new DataTable();
var ShowResult = from r in Result.AsEnumerable()
where Convert.ToInt32(r.Field<double>("ASLVAM") / r.Field<double>("GEST")) > 60
orderby Convert.ToInt32(r.Field<double>("ASLVAM") / r.Field<double>("GEST")) descending
select r;
DataTable newDataTbl = ShowResult.CopyToDataTable();
var anonType = newDataTbl.AsEnumerable()
.Select(r => new
{
pascode = r.Field<string>("PAS_CODE"),
melli = r.Field<string>("CODEMELI"),
name = r.Field<string>("NAM"),
family = r.Field<string>("FAMILY"),
bycode = r.Field<string>("BAYGANI"),
jancode = r.Field<string>("CODEJANBAZ"),
darsad = r.Field<int>("DARSAD"),
ostan = r.Field<string>("OSTAN_N"),
vacode = r.Field<string>("VA_CODE"),
moin = r.Field<string>("VA_MOIN"),
onvan = r.Field<string>("TAFZILI"),
aslvam = r.Field<double>("ASLVAM"),
gest = r.Field<double>("GEST"),
//tededGestKol = Convert.ToInt32(r.Field<double>("ASLVAM") / r.Field<double>("GEST")),
mandeVam = r.Field<double>("MANDE_VAM"),
dPardakht = r.Field<string>("DATE_P")
}
);
}
代替前一种方法,您可以使用以下扩展方法从List&lt;'T&gt;创建数据表。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.ComponentModel;
using System.Reflection;
namespace Common
{
public static class DataTableExtensions
{
public static DataTable ConvertToDataTable<T>(this IList<T> data)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
foreach (PropertyDescriptor prop in properties)
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
foreach (T item in data)
{
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
table.Rows.Add(row);
}
table.AcceptChanges();
return table;
}
public static DataRow ConvertToDataRow<T>(this T item, DataTable table)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(typeof(T));
DataRow row = table.NewRow();
foreach (PropertyDescriptor prop in properties)
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
return row;
}
public static T ConvertToEntity<T>(this DataRow tableRow) where T : new()
{
// Create a new type of the entity I want
Type t = typeof(T);
T returnObject = new T();
foreach (DataColumn col in tableRow.Table.Columns)
{
string colName = col.ColumnName;
// Look for the object's property with the columns name, ignore case
PropertyInfo pInfo = t.GetProperty(colName.ToLower(),
BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
// did we find the property ?
if (pInfo != null)
{
object val = tableRow[colName];
// is this a Nullable<> type
bool IsNullable = (Nullable.GetUnderlyingType(pInfo.PropertyType) != null);
if (IsNullable)
{
if (val is System.DBNull)
{
val = null;
}
else
{
// Convert the db type into the T we have in our Nullable<T> type
val = Convert.ChangeType(val, Nullable.GetUnderlyingType(pInfo.PropertyType));
}
}
else
{
// Convert the db type into the type of the property in our entity
SetDefaultValue(ref val, pInfo.PropertyType);
if (pInfo.PropertyType.IsEnum && !pInfo.PropertyType.IsGenericType)
{
val = Enum.ToObject(pInfo.PropertyType, val);
}
else
val = Convert.ChangeType(val, pInfo.PropertyType);
}
// Set the value of the property with the value from the db
if (pInfo.CanWrite)
pInfo.SetValue(returnObject, val, null);
}
}
// return the entity object with values
return returnObject;
}
private static void SetDefaultValue(ref object val, Type propertyType)
{
if (val is DBNull)
{
val = GetDefault(propertyType);
}
}
public static object GetDefault(Type type)
{
if (type.IsValueType)
{
return Activator.CreateInstance(type);
}
return null;
}
public static List<T> ConvertToList<T>(this DataTable table) where T : new()
{
Type t = typeof(T);
// Create a list of the entities we want to return
List<T> returnObject = new List<T>();
// Iterate through the DataTable's rows
foreach (DataRow dr in table.Rows)
{
// Convert each row into an entity object and add to the list
T newRow = dr.ConvertToEntity<T>();
returnObject.Add(newRow);
}
// Return the finished list
return returnObject;
}
}
}