1

私は次のようなdataTableクエリへのlinqを持っています:

`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>

クエリ結果をdataGridビューに表示するためにCopyToDataTable()メソッドを使用するための参照System.Data.DataSetExtentionsを追加しましたが、このメソッドはInellisenceに追加されませんでした。また、MSDNサンプルを使用してこのメ​​ソッドを使用しましたが、今回はこのエラー:「指定されたキャストは無効です」私を助けてください、この問題を克服するために何ができますか?

4

1 に答える 1

4

CopyToDataTable()は、クエリがIEnumerable<'DataRow>を返した場合にのみ機能します。クエリでは、匿名タイプを返しています。匿名型には、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<'T>からDatatableを作成できます。

        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;
                }
            }
        }
于 2012-09-15T13:11:57.370 に答える