【问题标题】:Generic class for convert list of object to IEnumerable<SqlDataRecord>将对象列表转换为 IEnumerable<SqlDataRecord> 的通用类
【发布时间】:2020-03-26 11:25:54
【问题描述】:

我有这个对象:

public class ConsentData
{
    public string ConsentName { get; set; }
    public bool ConsentValue { get; set; }
    public DateTime ConsentDate { get; set; }
}

我应该通过表值参数将 ConsentData 列表传递给 SQL Server 中的存储过程。

寻找一种将 ConsentData 列表转换为 SqlDataRecord 列表的方法,我在网络上找到了这个通用类:

public class SqlTableValueSupport<T> : List<T>, IEnumerable<SqlDataRecord> where T : class, new()
    {
        IEnumerator<SqlDataRecord> IEnumerable<SqlDataRecord>.GetEnumerator()
        {
            //Create Columns (SqlMetaData)
            List<SqlMetaData> records = new List<SqlMetaData>();
            var properties = typeof(T).GetProperties();
            foreach (var prop in properties)
            {
                SqlDbType sdbtyp = GetSqlType(prop.PropertyType);
                records.Add(new SqlMetaData(prop.Name, sdbtyp));
            }

            //Create records/rows (SqlDataRecord)
            SqlDataRecord ret = new SqlDataRecord(records.ToArray());

            foreach (T data in this)
            {
                for (int i = 0; i < properties.Length; i++)
                {
                    ret.SetValue(i, properties[i].GetValue(data, null));
                }

                yield return ret;
            }
        }

        // Map C# Types to SqlDbType
        private SqlDbType GetSqlType(Type type)
        {
            SqlDbType val = SqlDbType.VarChar;
            if (type == typeof(Int64) || type == typeof(Nullable<Int64>))
            {
                val = SqlDbType.BigInt;
            }
            else if (type == typeof(Byte[]))
            {
                val = SqlDbType.Binary;
            }
            else if (type == typeof(Boolean) || type == typeof(Nullable<Boolean>))
            {
                val = SqlDbType.Bit;
            }
            else if (type == typeof(DateTime) || type == typeof(Nullable<DateTime>))
            {
                val = SqlDbType.DateTime;
            }
            else if (type == typeof(Decimal))
            {
                val = SqlDbType.Decimal;
            }
            // Please refer to the following document to add other types
            // http://msdn.microsoft.com/en-us/library/ms131092.aspx
            return val;
        }
    }

我想知道如何使用该类,如何传递 ConsentData 列表并检索 SqlDataRecord 列表?

【问题讨论】:

  • 您不应该自己检索SqlDataRecord 的列表。该类正确地是reusingSqlDataRecord 的单个实例,因此它打算被枚举一次。该类本身应该存储数据,因此您应该将其用作List&lt;ConsentData&gt;。然后将该列表传递给SqlParameterValue 属性。您可能需要将其转换为 IEnumerable&lt;SqlDataRecord&gt;,因为该类也隐式为 IEnumerable&lt;ConsentData&gt;

标签: c# sql-server generics table-valued-parameters


【解决方案1】:

最后,我通过使用静态方法处理类来解决问题。 这是课程:

public class SqlTableValueSupport<T> where T : class
{
    public static DataTable ConvertData(List<T> ValuesList)
    {
        DataTable dtData = new DataTable();
        var objectReference = ValuesList.GetType().GetGenericArguments()[0];
        var properties = objectReference.GetProperties();
        foreach (var prop in properties)
        {
            dtData.Columns.Add(prop.Name, prop.PropertyType);
        }

        foreach (var item in ValuesList)
        {
            var dataArray = new List<object>();
            foreach (var prop in properties)
            {
                dataArray.Add(prop.GetValue(item));
            }

            dtData.Rows.Add(dataArray.ToArray());
        }

        return dtData;
    }
}

方法调用方式如下

var ListOfMyObjectDT = SqlTableValueSupport<MyObject>.ConvertData(ListOfMyObject);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多