星期日, 10月 12, 2025

[C#] FastMember-ObjectReader

FastMember github 上看見的使用方式,要把 List<T> 轉為 DataTable,重點在於 ObjectAccessor 使用

C# Code
namespace FastMemberDemo
{
    class Program
    {
        static void Main(string[] args)
        {

            List<Employee> dataSource = GenerateEmployees();

            // 範例一:ObjectReader.Create 搭配 DataTable.Load 產生 DataTable,
            //      因為 Employee Property 上有設定 OrdinalAttribute,
            //      所以 DataTable.DataColumn 會依設定順序產生
            DataTable dt = new DataTable(typeof(Employee).Name);

            using (var reader = ObjectReader.Create(dataSource))
                dt.Load(reader);

            PrintDataTableToConsole(dt);

            // 範例二:ObjectReader.Create 多載,指定特定欄位
            DataTable dtCols = new DataTable(typeof(Employee).Name);
            List<string> cols = new List<string>()
            {
                nameof(Employee.EmployeeID),
                nameof(Employee.EmployeeName)
            };

            using (var reader = ObjectReader.Create(dataSource, cols.ToArray()))
                dtCols.Load(reader);

            PrintDataTableToConsole(dtCols);
        }

        private static List<Employee> GenerateEmployees()
        {
            return new List<Employee>
            {
                new Employee
                {
                    EmployeeID = 1001,
                    EmployeeName = "王小明",
                    Birthday = new DateTime(1990, 5, 15),
                    Age = 35
                },
                new Employee
                {
                    EmployeeID = 1002,
                    EmployeeName = "陳美麗",
                    Birthday = new DateTime(1985, 12, 1),
                    Age = 40
                },
                new Employee
                {
                    EmployeeID = 1003,
                    EmployeeName = "林大華",
                    Birthday = new DateTime(2000, 1, 20),
                    Age = 25
                },
                new Employee
                {
                    EmployeeID = 1005,
                    EmployeeName = "黃建國",
                    Birthday = new DateTime(1975, 3, 30),
                    Age = 50
                },
                new Employee
                {
                    EmployeeID = 1006,
                    EmployeeName = "吳心怡",
                    Birthday = new DateTime(2002, 11, 11),
                    Age = 23
                },
                new Employee
                {
                    EmployeeID = 1007,
                    EmployeeName = "劉文傑",
                    Birthday = new DateTime(1988, 9, 25),
                    Age = 37
                },
                new Employee
                {
                    EmployeeID = 1009,
                    EmployeeName = "曾志偉",
                    Birthday = new DateTime(1980, 6, 8),
                    Age = 45
                },
                new Employee
                {
                    EmployeeID = 1010,
                    EmployeeName = "高慧君",
                    Birthday = new DateTime(2001, 4, 1),
                    Age = 24
                }
            };
        }

        public static void PrintDataTableToConsole(DataTable dt)
        {
            int totalWidth = 15;

            // --- 標題列 (欄位名稱) ---
            string header = "";

            foreach (DataColumn column in dt.Columns)
                header += column.ColumnName.PadRight(totalWidth);

            Console.WriteLine(header);

            // 分隔線
            Console.WriteLine(new string('-', header.Length));

            // --- 資料內容 ---
            foreach (DataRow row in dt.Rows)
            {
                string cellValue = string.Empty;
                string rowOutput = string.Empty;

                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    cellValue = row[i].ToString();
                    rowOutput += cellValue.PadRight(totalWidth);
                }

                Console.WriteLine(rowOutput);
            }
        }
    }

    public class Employee
    {
        [Ordinal(3)]
        public int EmployeeID { get; set; }

        [Ordinal(2)]
        public string EmployeeName { get; set; }

        [Ordinal(4)]
        public DateTime Birthday { get; set; }

        [Ordinal(1)]
        public int? Age { get; set; }
    }
}
Sample1 執行結果,根據 OrdinalAttribute 決定欄位順序
Sample2 執行結果,指定特定欄位

OrdinalAttribute SourceCode

實務上剛好有指定 DataTable 欄位順序需求,查 Code 時發現這段語法才知道有 FastMember.OrdinalAttribute 存在,省下不少麻煩

沒有留言:

張貼留言