问题
Im trying to read a row of information from a DB and write that out to a txt file. I have most of it figured out, but I get the following error "A field initializer cannot reference the non-static field, method, or property 'reader_writer.filewriter.filePath'" and I dont know why. Can someone please explain my problem?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data.SqlClient;
using System.Data.Common;
namespace reader_writer
{
public class filewriter
{
//public string filePath = "";
bool fileExists = false;
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string dbFile = filePath + @"\sqlfile.txt";
public void Main(string[] args)
{
fileExists = File.Exists(dbFile);
if (fileExists)
{
writeFileFromDB();
}
else
{
File.Create(dbFile);
writeFileFromDB();
}
}
public void writeFileFromDB()
{
//create connection
SqlCommand comm = new SqlCommand();
comm.Connection = new SqlConnection(@"MY DB CONNECTION STRING");
String sql = @"SELECT ROW1, ROW2
FROM Export.TABLENAME";
comm.CommandText = sql;
comm.Connection.Open();
SqlDataReader sqlReader = comm.ExecuteReader();
while (sqlReader.Read())
{
StreamWriter writer = File.CreateText(dbFile);
writer.WriteLine(sqlReader["ROW1"] + "\t" + sqlReader["ROW2"]);
writer.Close();
}
sqlReader.Close();
comm.Connection.Close();
}
}
}
回答1:
Here's a version that works as well as cleans it up a bit. It gets away from the wider scope variables that were causing your problem. It uses a way to write to the file that makes it so you don't have to detect if it exists already. It renames your ROW1 to ROW2 to columns which is what they actually are. And it makes it so it doesn't have to open/close the file every time you write a row.
static void Main(string[] args)
{
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string dbFile = filePath + @"\sqlfile.txt";
writeFileFromDB(dbFile);
}
public static void writeFileFromDB(string dbFile)
{
//create connection
SqlCommand comm = new SqlCommand();
comm.Connection = new SqlConnection(@"MY DB CONNECTION STRING");
String sql = @"SELECT COLUMN1, COLUMN2
FROM Export.TABLENAME";
comm.CommandText = sql;
comm.Connection.Open();
SqlDataReader sqlReader = comm.ExecuteReader();
// Open the file for write operations. If exists, it will overwrite due to the "false" parameter
using (StreamWriter file = new StreamWriter(dbFile, false))
{
while (sqlReader.Read())
{
file.WriteLine(sqlReader["COLUMN1"] + "\t" + sqlReader["COLUMN2"]);
}
}
sqlReader.Close();
comm.Connection.Close();
}
回答2:
string dbFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\sqlfile.txt";
Is there a reason why you're defining filePath, and then only using it to define dbFile?
回答3:
Set the dbFile
variable inside of the Main(string[] args)
method. It won't work in the class declaration.
回答4:
You can not reference to instance field without using a method or making the field static.
See the MSDN reference: http://msdn.microsoft.com/en-us/library/5724t6za(v=vs.80).aspx
回答5:
The problem appears to be that your dbFile is declared as a field (instance variable) of your class. But the Writer is not instantiated at the time of initialization.
The error you mentioned occurs when you declare and set a class-level variable to a non-static value. They cannot be used to initialise another field. Like you are doing in
StreamWriter writer = File.CreateText(dbFile);
You cannot use an instance variable to initialize another instance variable. The compiler can rearrange these.
There is no guarantee that dbfile will be initialized before writer.
Reserve field initializations to constant values or to a simple new statement.
来源:https://stackoverflow.com/questions/18000962/write-sql-info-to-a-txt-file