看到twMVC#21的投影片,有一段很有興趣。
感謝,分享者(Kevin Tseng)的文章 Dapper - 使用 LINQPad 快速產生相對映 SQL Command 查詢結果的類別,完整記載著方法。
謝謝作者的提醒,我看到片段太興奮就沒看到簡報最終有分享此篇文章。
LinqPad是非常強大的工具,你有在寫Linq,我想應該會很依賴這工具。
PS:開發者非常的友善,有問必答。只要你敢寫信給他。
LinqPad我是使用付費版本,所以,若有功能你沒有,我想請你花錢支持作者。
其中,使用 LINQPad 快速產生 SQL Command 對映的類別 這功能我眼睛一亮。
我曾經寫過小工具,透過點一點選一選的方式產生Pocos物件,同時帶有驗證等。
不過,有些情況,譬如說列表清單的POCOs物件,其實,要的相對來說就很單純。
但是,要怎麼快速做出來POCOs物件呢!?
這邊提出的方案就是透過Linq的功能 + 自訂擴充屬性來完成。
首先,我在網路上找到已經有人分享如何處理。
原文章:Generate C# POCOs from SQL statement in LINQPad By Necroskillz (沒想到,文章還沒寫完,已經得到作者允許直接貼程式碼了)。
以下程式碼擷取來源為該文章內容。
//Source From http://www.necronet.org/archive/2012/10/09/generate-c-pocos-from-sql-statement-in-linqpad.aspx/
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)
{
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.AppendLine("public class Info");
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} ", name, isNullable ? "?" : string.Empty, collumnName));
}
builder.AppendLine("}");
builder.AppendLine();
} while(reader.NextResult());
return builder.ToString();
}
}
你可以看到,將此程式貼上你Linq Pad 左下角打開的My Extensions。
打開以後,把原本所有的預設程式都刪除,將文章內的程式碼貼上。按下F5讓他進行編譯。
編譯以後,Linq 的Query選擇C# Program(很重要)。
因為該作者是透過擴充IDbConnection , 透過ExecuteReader來逐一讀取Select的欄位。
就文章內寫的除了一般Query,也可以處理Store Procedurs。
請注意,Select出來的一定要有欄位名稱唷!否則,屬性也會沒名字。
怎麼執行呢!?
因為該擴充屬性會回傳字串,所以,透過Console.Write輸出結果就好。
在Main區塊加入:
Console.WriteLine(this.Connection.DumpClass("Select * from Table"))
執行後,下方區塊就會依照寫的對應方法產生出POCO物件了。
public class Info
{
public int Id
public string Name
public int? TCount
}
很快速吧!不用自己一個一個Property打。
我個人建議可以調整程式的幾個地方:
- 加一個參數Class Name
- 不回傳字串物件,直接Console.Write輸出(這點好像就不夠物件導向XD)
想想,如果ViewModel要套驗證好像只能做到判斷Required。
所以,如果Model要套驗證歡迎大家試用我寫的工具,支援Sql Server & Oracle唷!!