从sqlite数据库执行者初始化c#对象的最佳实践是什么

时间:2018-07-26 10:39:45

标签: c# sqlite

考虑这样的sqlite表:

+--------------+-----------+--------------+ -----------+
| Col1(string) | Col2(int) | Col3(double) | ...        | 
+--------------+-----------+--------------+------------+
| A_string     | B_int     | C_double     | ...        |    
+--------------+-----------+--------------+------------+

...表示更多列的奇特之处。 目前,我们可以像这样从c#中的表中获取数据:

using( SQLiteConnection con = new SQLiteConnection( databaseConnectionString ) )
{
    con.Open(); //Open connection

    using( SQLiteCommand cmd = new SQLiteCommand( "SELECT * FROM table", con ) )
    {
        var dataTable = new DataTable();
        using( var sqlDataAdapter = new SQLiteDataAdapter( cmd ) )
        {
            sqlDataAdapter.Fill( dataTable );
            if( dataTable.Rows.Count > 0 ) //ensure, there are some results
            {
                foreach( DataRow row in dataTable.Rows )
                {
                    //Now initialize the c# objects
                    //But we do not wannt to hardcode every cast, 
                    //cause the type information is already in the database 
                    //therefore the function "getColumnValueAsRuntimeType()" is used to get the runntime type

                    string a = getColumnValueAsRuntimeType( "Col1", row );
                    int b    = getColumnValueAsRuntimeType( "Col2", row );
                    double c = getColumnValueAsRuntimeType( "Col3", row );
                    ...
                }
            }
        }
    }
}

private dynamic getColumnValueAsRuntimeType( string columnName, DataRow row )
{
    int index = row.Table.Columns.IndexOf( columnName );
    Type castTo = row.Table.Columns[ index ].DataType.UnderlyingSystemType;

    if( typeof( Int64 ) == castTo )
    {
        return Convert.ChangeType( row[ columnName ], typeof( Int32 ) );
    }

    return Convert.ChangeType( row[ columnName ], castTo );
}

由于调用:现在存在一些性能问题。

  int index = row.Table.Columns.IndexOf( columnName );
  Type castTo = row.Table.Columns[ index ].DataType.UnderlyingSystemType;

在函数“ getColumnValueAsRuntimeType()”处

所以我的主要问题是:

  1. 从C#中的sqlite数据库表获取数据的最快/性能最佳方式是什么?无需对源中的每个排印进行硬编码(我们不希望每次数据库类型更改时都重新编译源。数据库应该是主数据库)。而且为什么我仍然必须进行投射?我正在使用c#类访问数据库,数据应该已经输入。

我们在这里谈论的是具有1000列和数百万行的sqlite表。

1 个答案:

答案 0 :(得分:1)

我会使用类似Dapper的方法来处理映射。如果您创建一个与SQL语句返回的数据相对应的类,则Dapper将分析该类,并对返回的所有行一次为您执行列映射。

它看起来像这样:

public class DataClass
{
    public string Astring { get; set; }

    public int Bint { get; set; }

    public double Cdouble { get; set; }
}

您的sql语句看起来像

var sql = "SELECT Col1 Astring, Col2 Bint, Col3 Cbouble FROM table";

通过在SQL中使用别名,您可以处理不同的命名约定。 Manually Map column names with class properties

那你就要做

using( SQLiteConnection con = new SQLiteConnection( databaseConnectionString ) )
{
    con.Open();

    var dataClassList =  con.Query<DataClass>(sql);
} 

Dapper也可以处理嵌套对象: How do I map lists of nested objects with Dapper