我正在尝试使用OleDb CSV解析器从CSV文件中加载一些数据并将其插入到SQLite数据库中,但我使用OleDbAdapter.Fill
方法获得了一个异常,这令人沮丧:
未处理的类型异常 'System.Data.ConstraintException' 发生在System.Data.dll
中其他信息:未能成功 启用约束。一行或多行 包含违反非null的值, 唯一的或外键约束。
以下是源代码:
public void InsertData(String csvFileName, String tableName)
{
String dir = Path.GetDirectoryName(csvFileName);
String name = Path.GetFileName(csvFileName);
using (OleDbConnection conn =
new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
dir + @";Extended Properties=""Text;HDR=No;FMT=Delimited"""))
{
conn.Open();
using (OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM " + name, conn))
{
QuoteDataSet ds = new QuoteDataSet();
adapter.Fill(ds, tableName); // <-- Exception here
InsertData(ds, tableName); // <-- Inserts the data into the my SQLite db
}
}
}
class Program
{
static void Main(string[] args)
{
SQLiteDatabase target = new SQLiteDatabase();
string csvFileName = "D:\\Innovations\\Finch\\dev\\DataFeed\\YahooTagsInfo.csv";
string tableName = "Tags";
target.InsertData(csvFileName, tableName);
Console.ReadKey();
}
}
“YahooTagsInfo.csv”文件如下所示:
tagId,tagName,description,colName,dataType,realTime
1,s,Symbol,symbol,VARCHAR,FALSE
2,c8,After Hours Change,afterhours,DOUBLE,TRUE
3,g3,Annualized Gain,annualizedGain,DOUBLE,FALSE
4,a,Ask,ask,DOUBLE,FALSE
5,a5,Ask Size,askSize,DOUBLE,FALSE
6,a2,Average Daily Volume,avgDailyVolume,DOUBLE,FALSE
7,b,Bid,bid,DOUBLE,FALSE
8,b6,Bid Size,bidSize,DOUBLE,FALSE
9,b4,Book Value,bookValue,DOUBLE,FALSE
我尝试了以下内容:
这些都没有帮助......
一个限制是tagId应该是唯一的。这是表格在设计视图中的样子:
有人可以帮我弄清楚这里有什么问题吗?
更新
我将HDR属性从HDR=No
更改为HDR=Yes
,现在它没有给我一个例外:
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dir + @";Extended Properties=""Text;HDR=Yes;FMT=Delimited""");
我认为如果HDR=No
并且我删除了标题(即第一行),那么它应该可以工作......奇怪的是它不起作用。无论如何,现在我不再得到例外。
答案 0 :(得分:1)
第一件事:IMO对传输结构(例如数据集)进行密钥和约束处理是一个坏主意。
使用事务,如果需要,让目标数据库抛出。
第二:你检查过ds以确保csv被加载了吗? VS内置了数据集调试可视化工具 - 只需在加载ds后设置断点并将鼠标悬停在变量名称上,单击小向下箭头并选择相应的可视化工具。
第三:我认为你没有生成插入命令。在调用update之前,请检查InsertCommand.CommandText ..
var cmdText = sqliteAdapter.InsertCommand.CommandText;
我想你会发现它是空的。
这是最终被调用的SQLiteDataAdapter ctor的源代码。请注意,不使用命令构建器。您需要在SQLiteDataAdapter上显式设置InserCommand属性,可能是使用SQLiteCommandBuilder吗?
public SQLiteDataAdapter(string commandText, SQLiteConnection connection)
{
this.SelectCommand = new SQLiteCommand(commandText, connection);
}
答案 1 :(得分:0)
我将HDR属性从HDR=No
更改为HDR=Yes
和现在它不再给我一个例外 ...这是连接字符串的样子:
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dir + @";Extended Properties=""Text;HDR=Yes;FMT=Delimited""");
我假设如果HDR=No
并且我删除了标题(即第一行),那么它应该有效...如果我移除了HDR=No
,那么摆脱异常的唯一方法调用ds.EnforceConstraints = false;
无论如何,现在我不再得到例外。如果有人能解释为什么会发生这种情况,请告诉我们。