2011-05-05 198 views
9

我正在使用Dapper來找出一些需要訪問PostgreSQL數據庫的負載測試工具。這個特定版本的PostgreSQL原生不支持GUID,因此GUID值存儲爲32個字符的字符串。這些值使用someGuid.ToString("N")轉換爲字符串,轉換回Guid可以使用new Guid(stringValueFromColumn)完成。將字符串映射到Dapper的GUID

我的問題是如何讓Dapper讀取字符串並將它們轉換回Guids?

我試着修改DbType映射,但不起作用。

+0

雖然你在你的問題提這個突出的是,我錯過了你提到你正在使用「本機不支持GUID」的數據庫。值得注意的是,在數據庫中,可以將tSQL中的UNIQUEIDENTIFIER(或類似)映射到C#中的Guid([eg](https://github.com/StackExchange/dapper-dot-net/issues/447)) – dumbledad 2016-02-01 14:17:02

回答

16

或許要做到這一點(不等待短小精悍)最簡單的方法是讓第二個屬性:

public Guid Foo {get;set;} 

public string FooString { 
    get { return Foo.ToString("N"); } 
    set { Foo = new Guid(value); } 
} 

而在您的查詢中,別名爲FooString

當然,這就提示了這個問題:應該爲這種類型的東西支持私有屬性?我可以說:可能。

+0

那麼,這比在Dapper上劈手要乾淨一點。允許設置私有屬性(或字段)會很好。 – 2011-05-09 10:19:29

+0

@Marnix - 是的,我打算加入 – 2011-05-09 10:26:30

+0

@Marnix - 現在都存在,順便說一句(在源文件中 - 我還沒有取消部署nuget包) – 2011-05-09 12:56:47

2

我一起攻擊了一個解決方案。據我所知,沒有辦法指示Dapper爲特定類型生成備用綁定代碼,所以我修改了GetClassDeserializer方法以強制unbox類型爲字符串,如果屬性爲guid。 接下來,我重新使用了爲枚舉生成構造函數調用的代碼。

下面是修改後的代碼片段(在轉rf6d62f91f31a的761行開始):

// unbox nullable enums as the primitive, i.e. byte etc 
    var nullUnderlyingType = Nullable.GetUnderlyingType(item.Info.Type); 
    var unboxType = nullUnderlyingType != null && nullUnderlyingType.IsEnum ? nullUnderlyingType : item.Info.Type; 
    if(unboxType == typeof(Guid)) 
    { 
    unboxType = typeof (string); 
    } 
    il.Emit(OpCodes.Unbox_Any, unboxType); // stack is now [target][target][typed-value] 
    if ( (item.Info.Type == typeof(Guid) && unboxType == typeof(string)) 
     || (nullUnderlyingType != null && nullUnderlyingType.IsEnum)) 
    { 
    il.Emit(OpCodes.Newobj, item.Info.Type.GetConstructor(new[] { nullUnderlyingType ?? unboxType})); 
    } 

    il.Emit(OpCodes.Callvirt, item.Info.Setter); // stack is now [target]
+0

類型強制是我特意避免的,你會不會介意在我們的bug跟蹤器上發佈一個特性請求,看看它是否合適,請記住,如果postgres中的guid恰好爲31個字符長度,將會出現壯觀的爆炸。 .. – 2011-05-07 11:14:27

+0

@Sam - meh,GIGO;親自這會不會很困擾我。在此之前,L2S在這裏進行了一些*轉換(包括通過名稱作爲字符串的枚舉)。 – 2011-05-07 11:43:20

+0

@Sam謝謝,我發佈了功能請求。 – 2011-05-09 10:51:15

3

這是一個古老的問題,但我覺得它需要更新,因爲Dapper現在支持私有屬性,Marc在他的回答中引用了它。

private String UserIDString { get; set; } 
public Guid UserID 
{ 
    get 
    { 
     return new Guid(UserIDString); 
    } 
    private set 
    { 
     UserID = value; 
    } 
} 

然後在SQL給你的ID列的別名將其映射到私有財產,而不是實際的屬性:

SELECT UserID AS UserIDString FROM....