使用 Linq2DB 从 sqlite table 检索对象时出现 InvalidCastException
InvalidCastException when retrieving object from sqlite table using Linq2DB
我在尝试使用 Linq2db+SQLite 从 Sqlite table 获取记录时遇到问题,下面是我的 table
CREATE TABLE LogEntry
(
Time DATETIME NOT NULL ON CONFLICT ROLLBACK DEFAULT (CURRENT_TIMESTAMP),
Reference STRING NOT NULL ON CONFLICT ROLLBACK,
Team STRING,
Operator STRING,
ETMachine STRING,
CheckPoint BOOLEAN DEFAULT (0) NOT NULL
);
下面是C#代码:
using (var db = new DataConnection())
{
var newItem = new LogEntry()
{
CheckPoint = false,
ETMachine = "232323", // <= cause
Operator = "asdasd",
Reference = "asasas",
Team = "wewe",
Time = DateTime.Now
};
db.Insert<LogEntry>(newItem);
foreach (var item in db.LogEntries) //<= error occurs here
{
MessageBox.Show(string.Format("{0}:{1}", item.ID, item.Time));
}
}
和实体
[Table("LogEntry")]
public partial class LogEntry
{
[Column(Name = "ROWID"), NotNull, PrimaryKey, Identity] public int ID { get; set; } // datetime
[Column, NotNull ] public DateTime Time { get; set; } // datetime
[Column, NotNull ] public string Reference { get; set; } // string(max)
[Column, Nullable] public string Team { get; set; } // string(max)
[Column, Nullable] public string Operator { get; set; } // string(max)
[Column, Nullable] public string ETMachine { get; set; } // string(max)
[Column, NotNull ] public bool CheckPoint { get; set; } // boolean
}
我明白了
'System.InvalidCastException' occurred in System.Data.SQLite.dll
Additional information: Specified cast is not valid.
@ System.Data.SQLite.SQLiteDataReader.VerifyType(Int32 i, DbType typ)
@ System.Data.SQLite.SQLiteDataReader.GetString(Int32 i)
@ lambda_method(Closure , IDataReader )
@ LinqToDB.Expressions.ConvertFromDataReaderExpression.ColumnReader.GetValue(IDataReader dataReader) dans i:\linq2db\Source\Expressions\ConvertFromDataReaderExpression.cs:ligne 128
@ lambda_method(Closure , QueryContext , IDataContext , IDataReader , Expression , Object[] )
@ LinqToDB.Linq.Query`1.<Map>d__6a.MoveNext() dans i:\linq2db\Source\Linq\Query.cs:ligne 1218
@ Peel.FrmMain.Testdb2() dans C:\Users\Administrateur\Documents\Work\Projects\PeeL\src\Peel\FrmMain.cs:ligne 67
我搜索了一下,发现当 table 的字符串字段具有数值 ex 时,问题就会出现。 ETMachine
属性 以上,尽管该值作为字符串文字传递。
在这里,如果我将 232323
更改为 232a323
,它将正常工作。
我的问题是,如何强制 Linq2db 将值作为字符串而不是数字插入?
或者,如何强制 Linq2DB 获取值作为其适当的字段类型?
BTW 目标框架是 4.0。
我终于找到问题了,问题出在列数据类型 STRING
上,我将其更改为 TEXT
后它工作正常。
根据 SQLite 文档...
2.1 Determination Of Column Affinity
The affinity of a column is determined by the declared type of the column, according to the following rules in the order shown:
- If the declared type contains the string "INT" then it is assigned INTEGER affinity.
- If the declared type of the column contains any of the strings "CHAR", "CLOB", or "TEXT" then that column has TEXT affinity. Notice
that the type VARCHAR contains the string "CHAR" and is thus assigned
TEXT affinity.
- If the declared type for a column contains the string "BLOB" or if no type is specified then the column has affinity BLOB.
- If the declared type for a column contains any of the strings "REAL", "FLOA", or "DOUB" then the column has REAL affinity.
- Otherwise, the affinity is NUMERIC. Note that the order of the rules for determining column affinity is important. A column whose
declared type is "CHARINT" will match both rules 1 and 2 but the first
rule takes precedence and so the column affinity will be INTEGER.
在我的例子中它是 string
不包含 CHAR
然后类型是 NUMERIC
.
我在尝试使用 Linq2db+SQLite 从 Sqlite table 获取记录时遇到问题,下面是我的 table
CREATE TABLE LogEntry
(
Time DATETIME NOT NULL ON CONFLICT ROLLBACK DEFAULT (CURRENT_TIMESTAMP),
Reference STRING NOT NULL ON CONFLICT ROLLBACK,
Team STRING,
Operator STRING,
ETMachine STRING,
CheckPoint BOOLEAN DEFAULT (0) NOT NULL
);
下面是C#代码:
using (var db = new DataConnection())
{
var newItem = new LogEntry()
{
CheckPoint = false,
ETMachine = "232323", // <= cause
Operator = "asdasd",
Reference = "asasas",
Team = "wewe",
Time = DateTime.Now
};
db.Insert<LogEntry>(newItem);
foreach (var item in db.LogEntries) //<= error occurs here
{
MessageBox.Show(string.Format("{0}:{1}", item.ID, item.Time));
}
}
和实体
[Table("LogEntry")]
public partial class LogEntry
{
[Column(Name = "ROWID"), NotNull, PrimaryKey, Identity] public int ID { get; set; } // datetime
[Column, NotNull ] public DateTime Time { get; set; } // datetime
[Column, NotNull ] public string Reference { get; set; } // string(max)
[Column, Nullable] public string Team { get; set; } // string(max)
[Column, Nullable] public string Operator { get; set; } // string(max)
[Column, Nullable] public string ETMachine { get; set; } // string(max)
[Column, NotNull ] public bool CheckPoint { get; set; } // boolean
}
我明白了
'System.InvalidCastException' occurred in System.Data.SQLite.dll
Additional information: Specified cast is not valid.
@ System.Data.SQLite.SQLiteDataReader.VerifyType(Int32 i, DbType typ)
@ System.Data.SQLite.SQLiteDataReader.GetString(Int32 i)
@ lambda_method(Closure , IDataReader )
@ LinqToDB.Expressions.ConvertFromDataReaderExpression.ColumnReader.GetValue(IDataReader dataReader) dans i:\linq2db\Source\Expressions\ConvertFromDataReaderExpression.cs:ligne 128
@ lambda_method(Closure , QueryContext , IDataContext , IDataReader , Expression , Object[] )
@ LinqToDB.Linq.Query`1.<Map>d__6a.MoveNext() dans i:\linq2db\Source\Linq\Query.cs:ligne 1218
@ Peel.FrmMain.Testdb2() dans C:\Users\Administrateur\Documents\Work\Projects\PeeL\src\Peel\FrmMain.cs:ligne 67
我搜索了一下,发现当 table 的字符串字段具有数值 ex 时,问题就会出现。 ETMachine
属性 以上,尽管该值作为字符串文字传递。
在这里,如果我将 232323
更改为 232a323
,它将正常工作。
我的问题是,如何强制 Linq2db 将值作为字符串而不是数字插入? 或者,如何强制 Linq2DB 获取值作为其适当的字段类型?
BTW 目标框架是 4.0。
我终于找到问题了,问题出在列数据类型 STRING
上,我将其更改为 TEXT
后它工作正常。
根据 SQLite 文档...
2.1 Determination Of Column Affinity
The affinity of a column is determined by the declared type of the column, according to the following rules in the order shown:
- If the declared type contains the string "INT" then it is assigned INTEGER affinity.
- If the declared type of the column contains any of the strings "CHAR", "CLOB", or "TEXT" then that column has TEXT affinity. Notice that the type VARCHAR contains the string "CHAR" and is thus assigned TEXT affinity.
- If the declared type for a column contains the string "BLOB" or if no type is specified then the column has affinity BLOB.
- If the declared type for a column contains any of the strings "REAL", "FLOA", or "DOUB" then the column has REAL affinity.
- Otherwise, the affinity is NUMERIC. Note that the order of the rules for determining column affinity is important. A column whose declared type is "CHARINT" will match both rules 1 and 2 but the first rule takes precedence and so the column affinity will be INTEGER.
在我的例子中它是 string
不包含 CHAR
然后类型是 NUMERIC
.