开发者

c# set datarow DateTime field basing on DB type

开发者 https://www.devze.com 2023-03-19 12:49 出处:网络
I\'m writing a program which can use a SQLite DB or a MySql DB alternatively. (Depending if more than one has to use it, net infrastructure, etc...)

I'm writing a program which can use a SQLite DB or a MySql DB alternatively. (Depending if more than one has to use it, net infrastructure, etc...)

I've written a generic DBType interface and two classes that implement it based on the DB type. There is a function Dat开发者_如何学PythonaTable GetAllRows(tableName) that, as you expect, simply retrieves all the rows of a table and fills a System.Data.DataTable. For SQLite I've used the SQLIte connector and for MySql I've used the MySql connector.

Now the problem is when I read rows with the specialized DataReader (supplied from the connectors) the DataTable sets the column types with the types returned from this connectors. SQLite connector uses System.DateTime for the DateTime fields, MySql uses MySql.Data.Types.MySqlDateTime.

I've also implemented an entity-provider framework so I implicitly convert each retrieved DataRow into an Entity (on-demand) so the DateTime fields will become a DateTime field into the corresponding entity class.

For example, suppose that in the DB there is a table:

userTable: 
field "userName" as string,
field "date" as DateTime

with one row:

"asd" 2000/01/01

I call GetAllRows for this table, now I've a DataTable with 2 columns: the first column is a string field, the second column is System.DateTime or MySqlDateTime depending on the type of the DB I'm using for this run.

The row will be converted into an entity

class userTableEntity
{
    string name;
    DateTime data;

    /* methods... */

    implicit operator userTableEntity(DataRow row);
}

userTableEntity u = datarow; //uses the implicit operator

If I want to turn back and convert the entity into a DataRow I've to use something like this:

MyDataRow[userFieldName] = entity.name;
MyDataRow[dataFieldName] = entity.data;

If I'm using SQLite there is no problem. If I'm using MySql, the line MyDataRow[dataFieldName] = entity.data will throw a type exception because MyDataRow[dataFieldName] is of type MySqlDateTime but entity.data is a System.DateTime

Surely I can switch between SQLite/MySql before assigning the field but I've something like 75 tables with lots of DateTime field so I don't want to create a switch case (or a if) each time for obvious reasons.

I've tried making a MyDateTime class which performs an internal conversion with those operators:

implicit operator DateTime
implicit operator MySql.Data.Types.MySqlDateTime

but those operators will never been called because the type of the expression MyDataRow[dataFieldName] is object and not DateTime or MySqlDateTime! Neither I can write an implicit operator to object because MyDateTime class is subtype of object, so it's not permitted.

Note that MySql.Data.Types.MySqlDateTime has some useful methods:

public static explicit operator DateTime(MySqlDateTime val);
public DateTime GetDateTime();
public DateTime Value { get; }

and a ctor:

public MySqlDateTime(DateTime dt);

How can I arrange the code to do something like MyDataRow[dataFieldName] = entity.data without exceptions? I can change the type of entity.data but I don't want to do a switch case each time and I prefer to maintain the DataTable as it is read (no type changing in the columns).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号