I've a problem of fetching data from database, Because I'm new in c# Language. I thought that the ExecuteReader should retrieve all rows. by the way I can't access the data like full of object. and the reader.GetString(0) it's return to me only the index of array object.
Is any properties from c# to access the row from database?
I'm looking for the answer to solve this problem. I'd appropriated for the helping!
Here is the code I have so far:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Npgsql;
namespace Sample.Controllers
{
public class HomeController : Controller
{
public string Index()
{
var connString = "Host=localhost;Username=postgres;Password=123456;Database=dotnet_core_db";
using (var conn = new NpgsqlConnection(connString))
{
conn.Open();
// Retrieve all rows
using (var cmd = new NpgsqlCommand("SELECT * FROM Persons", conn))
using (var reader = cmd.ExecuteReader())
while (reader.Read())
{
Console.WriteLine(reader.GetString(0));
Console.WriteLine(reader.GetString(1));
Console.WriteLine(reader.GetString(2));
Console.WriteLine(reader.GetString(3));
Console.WriteLine(reader.GetString(4));
ViewData["connString"] = connString;
}
}
return connString;
}
public IActionResult Error()
{
ViewData["RequestId"] = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
return View();
}
}
}
Expectation Result
{
{
id: 92,
name: "foo",
last_name: "bar",
address: "adress Of foo",
city: "city of foo"
},
{
id: 872,
name: "foo1",
last_name: "bar 2",
address: "address of foo1",
city: "city of foo1"
}
}
you can do it like below one
using (var cmd = new NpgsqlCommand("SELECT * FROM Persons", conn))
{
using (var reader = cmd.ExecuteReader())
{
var columns = new List<string>();
for(int i=0;i<reader.FieldCount;i++)
columns.Add(reader.GetName(i));
JsonArrayCollection jsonArray = new JsonArrayCollection();
while (reader.Read())
{
JsonObjectCollection jsonObject = new JsonObjectCollection();
for(string columnName in columns)
jsonObject.Add(new JsonStringValue(columnName, reader[columnName]));
jsonArray.Add(jsonObject);
}
}
}
Written in notepad, so please excuse any compilation error.
Note: you can use any json library, only the syntax will change.
The data retrieval is okay. What you need is a json writing package. Consider library like json.net to ease the job.
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter writer = new JsonTextWriter(sw))
{
writer.Formatting = Formatting.Indented;
while (dataReader.Read())
{
writer.WriteStartObject();
for (int i = 0; i < dataReader.fieldCount; ++i)
{
writer.WritePropertyName(dataReader.GetName(i));
writer.WriteValue(dataReader.GetValue(i).ToString());
}
writer.WriteEndObject();
}
}
fileWriter.Write(sb.ToString());
Related
I wrote a program to SqlBulkCopy To Import CSV Data Into MYSQL database. In the function InsertDataIntoSQLServerUsingSQLBulkCopy triggering some errors as below snapshot.
I attached my source code down below. The errors are triggering on line 54.
using System;
using System.Data;
using Microsoft.VisualBasic.FileIO;
using System.Data.SqlClient;
namespace ReadDataFromCSVFile
{
static class Program
{
static void Main()
{
string csv_file_path = #"C:\Users\source\repos\WindowsService1\WindowsService1\bin\Debug\data.csv";
DataTable csvData = GetDataTabletFromCSVFile(csv_file_path);
Console.WriteLine("Rows count:" + csvData.Rows.Count);
Console.ReadLine();
}
private static DataTable GetDataTabletFromCSVFile(string csv_file_path)
{
DataTable csvData = new DataTable();
try
{
using (TextFieldParser csvReader = new TextFieldParser(csv_file_path))
{
csvReader.SetDelimiters(new string[] { "," });
csvReader.HasFieldsEnclosedInQuotes = true;
string[] colFields = csvReader.ReadFields();
foreach (string column in colFields)
{
DataColumn datecolumn = new DataColumn(column);
datecolumn.AllowDBNull = true;
csvData.Columns.Add(datecolumn);
}
while (!csvReader.EndOfData)
{
string[] fieldData = csvReader.ReadFields();
//Making empty value as null
for (int i = 0; i < fieldData.Length; i++)
{
if (fieldData[i] == "")
{
fieldData[i] = null;
}
}
csvData.Rows.Add(fieldData);
}
}
}
catch (Exception ex)
{
}
return csvData;
}
**line 54 function static void InsertDataIntoSQLServerUsingSQLBulkCopy(DataTable csvFileData) {
using (SqlConnection dbConnection = new SqlConnection("Data Source=.\SQLEXPRESS; Initial Catalog=MorganDB; Integrated Security=SSPI;"))
{
dbConnection.Open();
using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
{
s.DestinationTableName = "table1";
foreach (var column in csvFileData.Columns)
s.ColumnMappings.Add(column.ToString(), column.ToString());
s.WriteToServer(csvFileData);
}
}
}
}
}
If anyone could catch the error I'd be really appreciated. Thank you!
Are you getting confused with Visual BASIC? function is not a C# keyword. Replace function with either private or public, depending on the use case.
Also, you should be able to use System.IO instead of Microsoft.VisualBasic.FileIo in the includes.
I presume you've added the '**Line 54' to indicate where the error is?
From your screen grab it looks like the text function is present in the below though.
**line 54 function static void InsertDataIntoSQLServerUsingSQLBulkCopy(DataTable csvFileData) {
using (SqlConnection dbConnection = new SqlConnection("Data Source=.\SQLEXPRESS; Initial Catalog=MorganDB; Integrated Security=SSPI;"))
{
In C# you don't need to (in fact can't) declare function like you do in VB. The line should be:
static void InsertDataIntoSQLServerUsingSQLBulkCopy(DataTable csvFileData)
{
// Rest of code
}
I have an application which stores some data in a SQL database in a binary field. These data are serialized from a .net object in traditional .NET application with binary serialization. I'm writing a .net core application that needs to interface with the above but reading the binary data and making sense of them.
Ideally I want to be able just to deserialize these data with .net Core as if I was running full .net framework. The data itself are not complex, they are just a Dictionary<string,string> produced by the old asp.net profile provider.
I need to both read and write the binary data from .net core code.
I understand that support for BinaryFormatter is coming to .net core. In the meanwhile, is there anything not very complicated I can do right now to serialize / deserialize data with .net core as full .net framework would?
Looks like we have to write our own BinaryReader/BinaryWriter methods...
SCHEMA
CREATE TABLE dbo.BinaryTest (
BinaryData varbinary(max) NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CODE
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.IO;
namespace StackOverflow.ConsoleTester
{
public class Program
{
private const String SqlConnectionString = #"Server={Server};Database={Database};User={User};Password={Password};";
public static void Main(String[] args)
{
using (var db = new SqlConnection(SqlConnectionString))
{
var sqlCommand = new SqlCommand("DELETE FROM dbo.BinaryTest;", db) { CommandType = CommandType.Text };
db.Open();
sqlCommand.ExecuteNonQuery();
}
using (var db = new SqlConnection(SqlConnectionString))
{
var serializedData = new Dictionary<String, String> {{"key1", "value1"}, {"key2", "value2"}};
var binaryData = WriteBinaryData(serializedData);
var sqlCommand = new SqlCommand("INSERT INTO dbo.BinaryTest (BinaryData) VALUES (#BinaryData);", db) { CommandType = CommandType.Text };
var parameter = new SqlParameter("BinaryData", SqlDbType.VarBinary) {Value = binaryData};
sqlCommand.Parameters.Add(parameter);
db.Open();
sqlCommand.ExecuteNonQuery();
}
Dictionary<String, String> deserializedData = null;
using (var db = new SqlConnection(SqlConnectionString))
{
var sqlCommand = new SqlCommand("SELECT BinaryData FROM dbo.BinaryTest", db) { CommandType = CommandType.Text };
db.Open();
var reader = sqlCommand.ExecuteReader();
while (reader.Read())
{
deserializedData = ReadBinaryData(reader.GetSqlBinary(0));
}
}
if (deserializedData != null)
{
foreach (var item in deserializedData)
{
Console.WriteLine($"Key: {item.Key}; Value: {item.Value}");
}
}
Console.ReadKey();
}
private static Byte[] WriteBinaryData(Dictionary<String, String> data)
{
var memoryStream = new MemoryStream();
var binaryWriter = new BinaryWriter(memoryStream);
foreach (var item in data)
{
binaryWriter.Write(item.Key);
binaryWriter.Write(item.Value);
}
var binaryData = memoryStream.ToArray();
return binaryData;
}
private static Dictionary<String, String> ReadBinaryData(SqlBinary data)
{
var model = new Dictionary<String, String>();
var memoryStream = new MemoryStream(data.Value);
var binaryReader = new BinaryReader(memoryStream);
while (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
{
model.Add(binaryReader.ReadString(), binaryReader.ReadString());
}
return model;
}
}
}
Here is a piece of code:
XNamespace z = "#SomeSchema";
var listCols = new HashSet<Col>();
var colNameList = new List<string>(..some values..);
var xElementList = doc.Descendants(z + "row");
return new HashSet<Row>(xElementList .Select(x=> new Row
{
Col= new List<Col>(listCols).Select(col =>
{
col.Value= (string)x.Attribute(colNameList.First(colName=> colName == col.Name));
return col;
}).ToList()
}));
What is wrong is that, the return value contains a List of Row, but all of these rows have the exact same value (for the Col Value).
Ex, Row[1].Col[1].Value == Row[2].Col[2].Value
And these values should be completly different. I am obtaining those values from an Xml file. When I debug the xElementList, values are différents, but when I try to create rows with them, all rows are the same.
Actually, the Rows have the same Columns list, which is the last record of the xElementList.
Am I doing something wrong?
Thank you.
See code below. I read the xml twice. Once to get the columns names and add columns to table. Then read xml 2nd time to get row data.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
DataTable dt = new DataTable();
StreamReader sReader = new StreamReader(FILENAME, Encoding.GetEncoding(1252));
XmlReader reader = XmlReader.Create(sReader);
Dictionary<string, string> colDict = new Dictionary<string, string>();
while (!reader.EOF)
{
if (reader.Name != "FIELD")
{
reader.ReadToFollowing("FIELD");
}
if (!reader.EOF)
{
XElement field = (XElement)XElement.ReadFrom(reader);
string attrname = (string)field.Attribute("attrname");
string fieldtype = (string)field.Attribute("fieldtype");
switch (fieldtype)
{
case "string":
dt.Columns.Add(attrname, typeof(string));
break;
case "i4":
dt.Columns.Add(attrname, typeof(int));
break;
}
colDict.Add(attrname, fieldtype);
}
}
reader.Close();
sReader = new StreamReader(FILENAME, Encoding.GetEncoding(1252));
reader = XmlReader.Create(sReader);
while (!reader.EOF)
{
if (reader.Name != "ROW")
{
reader.ReadToFollowing("ROW");
}
if (!reader.EOF)
{
XElement row = (XElement)XElement.ReadFrom(reader);
DataRow newRow = dt.Rows.Add();
foreach (XAttribute attrib in row.Attributes())
{
string colName = attrib.Name.LocalName;
if (colDict.ContainsKey(colName))
{
switch (colDict[colName])
{
case "string":
newRow[colName] = (string)attrib;
break;
case "i4":
newRow[colName] = (int)attrib;
break;
}
}
}
}
}
}
}
}
Here is my code:
using (System.Net.WebResponse tmpRes = tmpReq.GetResponse())
{
using (System.IO.Stream tmpStream = tmpRes.GetResponseStream())
{
using (System.IO.TextReader tmpReader = new System.IO.StreamReader(tmpStream))
{
string fileContents = tmpReader.ReadToEnd();
for (int i = 0; i < fileContents.Length; i++)
{
if (fileContents[i] == "")
{
fileContents[i] = "null";
}
}
using (Stream s = GenerateStreamFromString(fileContents))
{}
}
}
}
this shows error 'string' to 'char' convert implicitly. Is there any other way to set "NULL" in empty fields in CSVReader
You are not using the CsvReader at all. You are also not splitting the string by your delimiter to get "cells". However, you can load a DataTable from the CsvReader and modify that.
Here's an example presuming tab as delimiter:
var tblCSV = new DataTable();
using (System.Net.WebResponse tmpRes = tmpReq.GetResponse())
using (System.IO.Stream tmpStream = tmpRes.GetResponseStream())
using (System.IO.TextReader tmpReader = new System.IO.StreamReader(tmpStream))
using (var csv = new CsvReader(tmpReader, true, '\t', '"', '\0', '\0', ValueTrimmingOptions.All))
{
csv.MissingFieldAction = MissingFieldAction.ParseError;
csv.DefaultParseErrorAction = ParseErrorAction.RaiseEvent;
csv.ParseError += csv_ParseError;
csv.SkipEmptyLines = true;
// load into DataTable
tblCSV.Load(csv, LoadOption.OverwriteChanges, csvTable_FillError);
}
Now loop the rows and columns and modify them accordingly:
foreach(DataRow row in tblCSV.Rows)
{
foreach(DataColumn col in tblCSV.Columns)
{
if(string.IsNullOrWhiteSpace(row.Field<string>(col)))
row.SetField(col, "null");
}
}
Update related to your comment:
I wants to add NULL value in empty cells in sql database when the csv
data Save in database. Is there any other way?
You could simply use the loop above to update your table instead:
using (var con = new SqlConnection("ConnectionString"))
{
con.Open();
foreach (DataRow row in tblCSV.Rows)
{
using (var cmd = new SqlCommand("INSERT INTO table(Col1,Col2) VALUES (#Col1,Col2);", con))
{
string col1 = row.Field<string>("Col1");
if (string.IsNullOrWhiteSpace(col1))
col1 = null;
string col2 = row.Field<string>("Col2");
if (string.IsNullOrWhiteSpace(col2))
col2 = null;
cmd.Parameters.AddWithValue("#col1", col1);
cmd.Parameters.AddWithValue("#col2", col2);
int inserted = cmd.ExecuteNonQuery();
}
}
}
I am using the following code to search items based on keywords:
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using ConsoleApplication1.EbayServiceReference;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TextWriter tw = new StreamWriter("1001.txt");
using (FindingServicePortTypeClient client = new FindingServicePortTypeClient())
{
MessageHeader header = MessageHeader.CreateHeader("My-CustomHeader", "http://www.mycustomheader.com", "Custom Header");
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageHeaders.Add(header);
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers.Add("X-EBAY-SOA-SECURITY-APPNAME", "myappid");
httpRequestProperty.Headers.Add("X-EBAY-SOA-OPERATION-NAME", "findItemsByKeywords");
httpRequestProperty.Headers.Add("X-EBAY-SOA-GLOBAL-ID", "EBAY-US");
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
FindItemsByKeywordsRequest request = new FindItemsByKeywordsRequest();
request.keywords = "gruen wristwatch parts -(sara,quartz,embassy,bob,robert,elephants,adidas)";
FindItemsByKeywordsResponse check = client.findItemsByKeywords(request);
int totalEntries = check.paginationOutput.totalEntries;
Console.WriteLine(totalEntries);
int totalPages = (int)Math.Ceiling((double)totalEntries / 100.00);
for (int curPage = 1; curPage <= totalPages; curPage++)
{
PaginationInput pagination = new PaginationInput();
pagination.entriesPerPageSpecified = true;
pagination.entriesPerPage = 100;
pagination.pageNumberSpecified = true;
pagination.pageNumber = curPage;
request.paginationInput = pagination;
FindItemsByKeywordsResponse response = client.findItemsByKeywords(request);
foreach (var item in response.searchResult.item)
{
Console.WriteLine(item.viewItemURL.ToString());
tw.WriteLine(item.viewItemURL.ToString());
}
}
}
}
tw.Close();
Console.WriteLine("end");
Console.ReadKey();
}
}
}
Here is the original keyword set:
gruen wristwatch parts -sara -quartz -embassy -bob -robert -elephants -adidas
If i use this keyword set it returns 3 items: The result is here
I have formatted it like this to use in FindingAPI according to this reference
gruen wristwatch parts -(sara,quartz,embassy,bob,robert,elephants,adidas)
and it returns 13 items. I think it should return 3 items too.
What is responsible for the discrepancy, and can I get the expected results using the alternate syntax?