2013-07-22 20 views
2

我需要在Dapper中支持SQL Server CE的ntext類型。這裏有一個線程描述了這個問題: https://code.google.com/p/dapper-dot-net/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary&groupby=&sort=&id=110正在嘗試修改Dapper以支持SQL Server CE的ntext類型

我試圖修改小巧玲瓏使用類似於PetaPoco使用的方法解決: https://github.com/cyotek/PetaPoco/commit/ea13add473be3899ebb73b463d2aff98f8d6d06e

通過短小精悍的源採取一看後,我決定嘗試此操作的好方法可能是修改DbString類。我改變了AddParameter(IDbCommand command, string name)方法(開始於3120線),以執行以下操作:

public void AddParameter(IDbCommand command, string name) 
{ 
      if (IsFixedLength && Length == -1) 
      { 
       throw new InvalidOperationException("If specifying IsFixedLength, a Length must also be specified"); 
      } 
      var param = command.CreateParameter(); 
      param.ParameterName = name; 
      param.Value = (object)Value ?? DBNull.Value; 
      if (Length == -1 && Value != null && Value.Length <= 4000) 
      { 
       param.Size = 4000; 
      } 
      else 
      { 
       param.Size = Length; 
      } 
      param.DbType = IsAnsi ? (IsFixedLength ? DbType.AnsiStringFixedLength : DbType.AnsiString) : (IsFixedLength ? DbType.StringFixedLength : DbType.String); 

      if (param.Value != null) 
      { 
       if (param.Value.ToString().Length + 1 > 4000 && param.GetType().Name == "SqlCeParameter") 
       { 
        param.GetType().GetProperty("SqlDbType").SetValue(param, System.Data.SqlDbType.NText, null); 
       } 
      } 

      command.Parameters.Add(param); 
} 

我的編輯是實現這一檢查類型,並嘗試將其改爲ntext底部的一部分。但是,當我運行此代碼時,IIS Express崩潰,並且asp.net不會提供任何有用的調試信息。我試圖在調試器中運行它,並且出現堆損壞相關錯誤。

我在這裏錯了嗎?有沒有更好的方式在Dapper中嘗試這樣的事情?或者這是因爲高速緩存和/或IL生成方式而無法正常工作的東西?我希望能夠爲它創建一個拉取請求,如果我能得到它的工作,但我正在脫穎而出。


更新 - 我找到了一個可能的解決方案。我在DynamicParameters類中的AddParameters(IDbCommand command, SqlMapper.Identity identity)方法中添加了一些代碼。現在閱讀方法的最後一行:

if (s != null) 
{ 
    if (s.Length + 1 > 4000 && p.GetType().Name == "SqlCeParameter")  
    { 
     p.GetType().GetProperty("SqlDbType").SetValue(p, SqlDbType.NText, null); 
     p.Size = s.Length; 
    } 
} 
if (add) 
{ 
    command.Parameters.Add(p); 
} 
param.AttachedParam = p; 

爲了使用此解決方案,我必須將我的參數添加爲DynamicParameters。所以它有效,但不是最有用的方式。我仍在尋找更好的解決方案。

如果我創建一個pull請求,Dapper開發人員會考慮將其包含爲修補程序嗎?

+0

「這是那種事了小巧玲瓏的開發者會考慮包括作爲補丁,如果我創建了一個拉請求?「我會在github網站上提問。雖然可能有一些機會,但這個問題永遠不會在這裏看到。 – Hogan

回答

1

試試這個擴展方法中的任何財產包:

public static class DynamicParametersExtensions 
{ 
    public static DynamicParameters AsDynamic(this object propertyBag) { 
     var parameters = new DynamicParameters(); 
     foreach (var property in propertyBag.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) { 
      var propertyValue = property.GetValue(propertyBag); 
      var propertyValueAsString = propertyValue as string; 
      if (propertyValueAsString != null && propertyValueAsString.Length >= 4000) { 
       parameters.Add(property.Name, new DbString { 
        Value = propertyValueAsString, 
        Length = propertyValueAsString.Length 
       }); 
      } else { 
       parameters.Add(property.Name, propertyValue); 
      } 
     } 
     return parameters; 
    } 
} 

使用例:

connection.Execute(@"UPDATE MyTable SET [email protected]", new { value.NTextColumn }.AsDynamic()); 
相關問題