手動建立 OR-M 的 POCO 可是一件苦差事,針對 EF 不支援的資料庫,透過這個小技巧,可以大大提升程式設計師的生產力、降低錯誤發生,團隊使用 EF開發資料庫,但 AS400 並沒有支援 EF的 Provider,怎麼辦,我再也不會回頭使用弱型別的 DataTable 了,這時候 Dapper 就派上用場,請參考:https://www.dotblogs.com.tw/yc421206/2015/04/20/as400_connect_provider
使用 ORM 的要先準備好POCO ,欄位只要一多,手動建立 POCO 多累人阿,本來想自幹 Parser 產生 POCO,還好,自幹之前找到了 Kevin 的 BLog:http://kevintsengtw.blogspot.tw/2015/10/dapper-linqpad-sql-command.html,Kevin 有你真好
重點就是以下的擴充方法,以下代碼節錄 Kevin 的 BLog:
public static class LINQPadExtensions
{
private static readonly Dictionary<Type, string> TypeAliases = new Dictionary<Type, string>()
{
{ typeof(int), "int" },
{ typeof(short), "short" },
{ typeof(byte), "byte" },
{ typeof(byte[]), "byte[]" },
{ typeof(long), "long" },
{ typeof(double), "double" },
{ typeof(decimal), "decimal" },
{ typeof(float), "float" },
{ typeof(bool), "bool" },
{ typeof(string), "string" }
};
private static readonly HashSet<Type> NullableTypes = new HashSet<Type>()
{
typeof(int),
typeof(short),
typeof(long),
typeof(double),
typeof(decimal),
typeof(float),
typeof(bool),
typeof(DateTime)
};
public static string DumpClass(this IDbConnection connection, string sql, string className = "Info")
{
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
var cmd = connection.CreateCommand();
cmd.CommandText = sql;
var reader = cmd.ExecuteReader();
var builder = new StringBuilder();
do
{
if (reader.FieldCount <= 1) { continue; }
builder.AppendFormat("public class {0}{1}", className, Environment.NewLine);
builder.AppendLine("{");
var schema = reader.GetSchemaTable();
foreach (DataRow row in schema.Rows)
{
var type = (Type)row["DataType"];
var name = TypeAliases.ContainsKey(type) ? TypeAliases[type] : type.Name;
var isNullable = (bool)row["AllowDBNull"] && NullableTypes.Contains(type);
var collumnName = (string)row["ColumnName"];
builder.AppendLine(string.Format("\tpublic {0}{1} {2} {{ get; set; }}", name, isNullable ? "?" : string.Empty, collumnName));
builder.AppendLine();
}
builder.AppendLine("}");
builder.AppendLine();
} while (reader.NextResult());
return builder.ToString();
}
}
上面的程式碼邏輯很簡單,就是透過 Select 語法把 Table 欄位找過一遍並依照 Table 欄位產生類別欄位,利用 LINQPad Dump() 呈現結果,最後把類別複製到專案就可以用了
當然,這並非是一個最完美的作法,還有很大的空間可以改善,對我而言就很夠用了;
平時有用 LINQPad 來處理輸出結果的人,應該都很享受 LINQPad Dump() 的功能,本人是很喜愛這功能的,還沒體驗過LINQPad的夥伴,趕緊加入吧。
這個擴充方法是針對 IDbConnection 型別進行擴充 (Dapper 也是如此),也就是說所有實作 IDbConnection 的衍生類別都能享有這功能,當不能用 EF 產生 POCO/DTO 時,這個擴充方法就是一個相當好用的小技巧。
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET