C# Code
using System.Data.Entity; using System.Reflection; namespace DataGridView4CellFormatting { public partial class Form2 : Form { EFDbContext context; BindingSource bsOrder; public Form2() { InitializeComponent(); context = new EFDbContext(); bsOrder = new BindingSource(); } private void Form2_Load(object sender, EventArgs e) { context.Order.Include(c => c.Customer).Load(); bsOrder.DataSource = context.Order.Local.ToBindingList(); dgvOrders.AutoGenerateColumns = false; dgvOrders.DataSource = bsOrder; } private readonly char DataPropertyNameSign = '.' ; private void dgvOrders_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) { object obj = dgvOrders.Rows[e.RowIndex].DataBoundItem; string DataPropertyName = dgvOrders.Columns[e.ColumnIndex].DataPropertyName; if (obj != null && DataPropertyName.Contains(DataPropertyNameSign)) { e.Value = BindNavigationProperty(obj, DataPropertyName); } } /// <summary> /// 註解以該範例來說明註記,方便事後回憶 /// </summary> /// <param name="Property">Order Class</param> /// <param name="DataPropertyName">Customer.CustName</param> /// <returns>CustName 資料</returns> private string BindNavigationProperty(object Property, string DataPropertyName) { if (DataPropertyName.Contains(DataPropertyNameSign) == false) { throw new Exception($"{nameof(DataPropertyName)} 資料不符合導覽屬性規則"); } // Customer.CustName var DataPropertyInfo = ParseDataPropertyName(DataPropertyName); // Customer string NavigatrionPropertName = DataPropertyInfo.NavigationPropertyName; // CustName string PropertyName = DataPropertyInfo.PropertyName; // 取回 Order.Customer 相關資料 var obj = GetPropertyValue(Property, NavigatrionPropertName); // 取回 Customer.CustName 資料 return GetPropertyValue(obj, PropertyName).ToString(); } /// <summary> /// 取得 object Property Value /// </summary> /// <param name="obj">欲取值的 object </param> /// <param name="propertyName">屬性</param> /// <returns>屬性值</returns> private object GetPropertyValue(object obj, string propertyName) { Type t = obj.GetType(); // BindingFlags.IgnoreCase 表示不區分大小寫,Flag 只要重新設定就要全部都設,只設單一個會沒有效果 PropertyInfo info = t.GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); if (info == null) { throw new Exception($"Property:{nameof(propertyName)} 不存在,無法取值"); } object oValue = info.GetValue(obj, null); if (oValue == null) { throw new Exception($"無法取得 Property:{nameof(propertyName)} 的值"); } return oValue; } /// <summary> /// 解析 DataPropertyName /// </summary> /// <param name="DataPropertyName">DataPropertyName</param> /// <returns>ClassName 和 PropertyName </returns> private (string NavigationPropertyName, string PropertyName) ParseDataPropertyName(string DataPropertyName) { if (string.IsNullOrEmpty(DataPropertyName)) { throw new ArgumentNullException(nameof(DataPropertyName)); } string[] result = DataPropertyName.Split(DataPropertyNameSign); int ArraryLength = 2; if (result.Length != ArraryLength) { string ErrorMessage = $"{nameof(DataPropertyName)} 參數格式必須為 ClassName.PropertyName,傳入值為 {DataPropertyName}"; throw new ArgumentException(ErrorMessage); } return (result[0], result[1]); } } }
- 重點1:BindingFlags.IgnoreCase [Highlight 76 77 行]
- 重點2:SQL Profile 側錄 TSQL 語法
沒有留言:
張貼留言