2014-11-24 12 views
7

Bir BIGINT sütununda keneler olarak kodlanmış bir süreye sahip bir tabloya sahip varolan bir veritabanı formatıyla arabirim oluşturmak için Dapper'ı kullanmaya çalışıyorum. Dapper'a, POCO'nun TimeSpan -tipi özelliğini benim veritabanına ekleyip okurken keneleri işaretlemek için nasıl söylerim?SQLite ve Dapper'taki Timeping'in Eşlemesi

Ben TimeSpan DbType.Int64 için tip harita ayarlamak için denedim

:

SqlMapper.AddTypeMap(typeof(TimeSpan), DbType.Int64); 

Ve ayrıca bir ITypeHandler oluşturduk fakat SetValue yöntem asla denir: İşte

public class TimeSpanToTicksHandler : SqlMapper.TypeHandler<TimeSpan> 
{ 
    public override TimeSpan Parse(object value) 
    { 
     return new TimeSpan((long)value); 
    } 

    public override void SetValue(IDbDataParameter parameter, TimeSpan value) 
    { 
     parameter.Value = value.Ticks; 
    } 
} 

benim POCO'm:

Wh Ben TimeSpan bırakırsanız

System.InvalidCastException : Unable to cast object of type 'System.TimeSpan' to type 'System.IConvertible'. 
    at System.Convert.ToInt64(Object value, IFormatProvider provider) 
    at System.Data.SQLite.SQLiteStatement.BindParameter(Int32 index, SQLiteParameter param) 
    at System.Data.SQLite.SQLiteStatement.BindParameters() 
    at System.Data.SQLite.SQLiteCommand.BuildNextCommand() 
    at System.Data.SQLite.SQLiteCommand.GetStatement(Int32 index) 
    at System.Data.SQLite.SQLiteDataReader.NextResult() 
    at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave) 
    at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior) 
    at System.Data.SQLite.SQLiteCommand.ExecuteNonQuery(CommandBehavior behavior) 
    at System.Data.SQLite.SQLiteCommand.ExecuteNonQuery() 
    at Dapper.SqlMapper.ExecuteCommand(IDbConnection cnn, ref CommandDefinition command, Action`2 paramReader) in SqlMapper.cs: line 3310 
    at Dapper.SqlMapper.ExecuteImpl(IDbConnection cnn, ref CommandDefinition command) in SqlMapper.cs: line 1310 
    at Dapper.SqlMapper.Execute(IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Nullable`1 commandTimeout, Nullable`1 commandType) in SqlMapper.cs: line 1185 

:

string sql = "INSERT INTO Tasks (Duration) values (@Duration);"; 

Ve eklemek için nesne olarak POCO geçen:

Task task = new Task { Duration = TimeSpan.FromSeconds(20) }; 
connection.Execute(sql, task); 

Bu durum almak böyle basit bir insert deyimi yürütme tr eşleme türü (varsayılan olarak DbType.Time), TimeSpan, yani "00: 00: 20.000" dize sürümünü yazıyor. sütundaki diğer verilerin rmat'ı.

+0

DB tipinden benim tipime. – juharr

+0

Neden düşüş ...? –

cevap

2

Bunun yerine aşağıdakileri yapabilir misiniz? LinqToDB için

public class Task 
{ 
    public TimeSpan Duration { get; set; } 
    public long Ticks 
    { 
     get { return Duration.Ticks; } 
     set { Duration = new TimeSpan(value); } 
    } 
    // etc. 
} 

string sql = "INSERT INTO Tasks (Duration) values (@Ticks);"; 
+0

Ben bir Dapper acemi olarak, kütüphanenin sağladığı bir şey olduğunu umuyordum. Tüm "ITypeHandler" ve benzeri diğer arayüzlerle olması gerektiği gibi görünüyor ... –

1

Çözümleri:

MappingSchema.SetDataType(typeof(TimeSpan), DataType.NText); 

Veya:

MappingSchema.SetDataType(typeof(TimeSpan), DataType.Int64); 

Örnek: Hep çevirisini yapan ikinci bir özellik oluşturarak bu çözdük

public class Program 
{ 
    private const string ConnectionString = "Data Source=:memory:;Version=3;New=True;"; 

    public static void Main() 
    { 
     var dataProvider = new SQLiteDataProvider(); 

     var connection = dataProvider.CreateConnection(ConnectionString); 
     connection.Open(); 

     var dataConnection = new DataConnection(dataProvider, connection); 

     dataConnection.MappingSchema.SetDataType(typeof(TimeSpan), DataType.Int64); 

     dataConnection.CreateTable<Category>(); 

     dataConnection.GetTable<Category>() 
      .DataContextInfo 
      .DataContext 
      .Insert(new Category 
      { 
       Id = 2, 
       Time = new TimeSpan(10, 0, 0) 
      }); 


     foreach (var category in dataConnection.GetTable<Category>()) 
     { 
      Console.WriteLine([email protected]"Id: {category.Id}, Time: {category.Time}"); 
     } 
    } 

    private class Category 
    { 
     public int Id { get; set; } 
     public TimeSpan Time { get; set; } 
    } 
}