i want to write query which is written using linq and data dictionary i want to convert that query in ado.net form
var insData = new Dictionary<string, string>();
insData = db.Query<TableName>("select Name, Value from Table where PId={id} and type<>{(int)Enum.PElement}").ToDictionary(key => key.Name??t.TName, Val => Val.Value);
This above is the query i want to convert it into ado.net form to provide dictionary with this type
ToDictionary(key => key.Name??t.TName, Val => Val.Value);
i have written half of the code untill to fill the dataset
but further i am quite confused how to go further to convert it to dictionary with keypair value shown above.
Here is the code what i have tried
var dictonary = new SqlCommand($"select Name, Value from Table where PId={id} and type<>{(int)Enum.PElement}", con);
SqlDataAdapter sda2 = new SqlDataAdapter(dictonary);
DataSet ds2 = new DataSet();
sda2.Fill(ds2);
IEnumerable<DataRow> dataRows = ds2.Tables[0].Rows.Cast<DataRow>().ToList();
var insData = new Dictionary<string, string>();
foreach (DataRow row2 in dataRows )
{
insData.ToDictionary(key => key.Name ?? t.TName, Val => Val.Value);
}
but i am getting error like
Keypair value does not contain defination of Name and no accessible >extension method Name accepting first argument of type KeyValuepair
I want to work that query in ado.net like it is working in linq which i have shown above.
I will do something like this :
IEnumerable<DataRow> dataRows;
using (var dataSet = new DataSet())
{
using (var command = new SqlCommand($"select Name, Value from Table where PId={id} and type<>{(int) Enum.PElement}", con))
{
using (var sda2 = new SqlDataAdapter(command))
{
sda2.Fill(dataSet);
}
}
dataRows = dataSet.Tables[0].Rows.OfType<DataRow>();
}
return dataRows.ToDictionary(row => row["Name"].ToString(), row => row["Value"].ToString());
Related
This questions had been posted several times (1,2,3,4), but I did not find one that would apply to my case.
I have a Dictionary with the structure:
public Dictionary<Int32, PhaseMag> Data;
Where PhaseMag:
public struct PhaseMag
{
public Single Magnitude;
public Single Phase;
}
Each Key value will contain two 2 values (Mag. and Phase). If you prefer to see an image.
I need to store all the content of this Dictionary in a unique Table in the DB (Microsoft SQL). Each line of the Dictionary should become one line of my DB Table. My final table will contain 3 fields, 1) Key 2) Mag and 3) Phase. For example, if I have 30 Keys, my table will contain 30 lines, one for each key.
My ideas:
Create a foreach loop based on each Key and create an insert into to the DB (one for Key->Mag and other for Key->Phase). But I don't think that this will be the best approach, especially, because my dictionary contains several thousand of lines.
So, what should be my approach to do this? I simply need to save my Dictionary into the DB, which each line of the Dic. will be one line from the DB.
Assume you're using SQL Server, here're two of many options you have:
Bulk insert, it's recommended.
public void BulkWrite(Dictionary<Int32, PhaseMag> data)
{
var dataTable = new DataTable();
dataTable.Columns.Add(new DataColumn { DataType = typeof(int), ColumnName = "Key" });
dataTable.Columns.Add(new DataColumn { DataType = typeof(Single), ColumnName = "Magnitude" });
dataTable.Columns.Add(new DataColumn { DataType = typeof(Single), ColumnName = "Phase" });
foreach (var x in data)
{
var r = dataTable.NewRow();
dataTable.Rows.Add(r);
r[0] = x.Key;
r[1] = x.Value.Magnitude;
r[2] = x.Value.Phase;
}
using (var conn = new SqlConnection("conneciton string"))
{
conn.Open();
using (var bulkCopy = new SqlBulkCopy(conn))
{
bulkCopy.BatchSize = 4000;
bulkCopy.DestinationTableName = "YorTableName";
bulkCopy.WriteToServer(dataTable);
}
}
}
Multiple inline query, executed as batch. As all your data are number, so low risk of SQL injection even using inline query.
public void InlineQueryWrite(Dictionary<Int32, PhaseMag> data)
{
using (var conn = new SqlConnection("conneciton string"))
{
conn.Open();
foreach (var bulk in data.Select((d, i) => new {d, i}).GroupBy(x => x.i % 10))
{
var sb = new StringBuilder();
foreach (var x in bulk)
{
sb.AppendFormat("Insert Into Your_Table (Key, Magnitude, Phase) Values ({0},{1},{2});", x.d.Key, x.d.Value.Magnitude, x.d.Value.Phase);
}
using (var command = conn.CreateCommand())
{
command.CommandText = sb.ToString();
command.ExecuteNonQuery();
}
}
}
}
I haven't ran/tested through the code, but they should work.
Client application sends a json array to my .net application. I'm receiving it using name value collection. Now I want to read it's value and assign it to an IN clause of a SQL query.
HttpContext context = HttpContext.Current;
NameValueCollection nvc = context.Request.Form;
string co_json = nvc["co_json"];
// jsArray : [{"roll_number":"11","mark":"68"},{"roll_number":"22","mark":"70"}]";
// I want to get the two roll numbers from above json and need to pass it to SQL
SqlDataAdapter da = new SqlDataAdapter("select * from student_details where roll_number IN ( ???) ", con);
DataTable dt = new DataTable();
da.Fill(dt);
You can convert the json to a custom c# object using Newtonsoft JSON.NET
You can create a class like this:
public class RollMark
{
public string roll_number {get;set;}
public string mark {get;set;}
}
now you can do this:
HttpContext context = HttpContext.Current;
NameValueCollection nvc = context.Request.Form;
string co_json = nvc["co_json"];// jsArray : [{"roll_number":"11","mark":"68"},{"roll_number":"22","mark":"70"}]";
//collect all rollMarks in json to c# list
var rollMarks = Newtonsoft.Json.JsonConvert.DeserializeObject<List<RollMark>>(co_json );
And you can now add parameters in your query like this:
//format your IN query
string[] paramArray = rollMarks.Select(x, i) => "#settings" + i).ToArray();
string query = string.Format("select * from student_details where roll_number IN ({0})", string.Join(",", paramArray));
SqlDataAdapter da = new SqlDataAdapter(query, con);
DataTable dt = new DataTable();
for (int i = 0; i < rollMarks.Count(); ++i)
{
da.SelectCommand.Parameters.AddWithValue("#settings", rollMarks[i].roll_number)
}
da.Fill(dt);
First of all, split your json array to find each item of array. next, create a class that has each proprties of your item. finally deserialize your each json item to the class.
We are currently querying the Oracle DB and returning the result in the JSON format.The Query results are returning the more duplicate rows. The Controller is something like below
public HttpResponseMessage Getdetails([FromUri] string[] Column)
{
List<string> selectionStrings = new List<string>();
string connStr = ConfigurationManager.ConnectionStrings["PConnection"].ConnectionString;
using (OracleConnection dbconn = new OracleConnection(connStr))
{
DataSet userDataset = new DataSet();
var colDict = new Dictionary<string, string>()
{
{"CATEGORY", "STCD_PRIO_CATEGORY_DESCR.DESCR"},
{"SESSION_NUMBER", "STCD_PRIO_CATEGORY_DESCR.SESSION_NUM"},
{"SESSION_START_DATE","Trunc(STCD_PRIO_CATEGORY_DESCR.START_DATE)"},
{"SESSION_START_TIME","STCD_PRIO_CATEGORY_DESCR.START_DATE"}}};
foreach (string col in Column)
{
string selector = colDict[col];
selectionStrings.Add(string.Format("{0} AS {1}", selector, col));
}
string selectString = string.Join(",", selectionStrings);
var strQuery = string.Format(#"SELECT {0}
FROM
STCD_PRIO_CATEGORY_DESCR", selectString);
}}}
So if I just add Distinct in the Select statement as
var strQuery = string.Format(#"SELECT DISTINCT {0}
FROM
STCD_PRIO_CATEGORY_DESCR", selectString);
is that should be enough? Or should we be putting DISTINCT before all the Column names
Use distinct or if you are still having trouble you can move the data result into a list and use linq to select only the unique rows.
var result = myList.GroupBy(test => test.id)
.Select(grp => grp.First())
.ToList();
taken from: Select distinct using linq
I want to perform insert into database but in different Tables. Each record i have in my file is assigned with the table Identifiers which will be used as a key. For now what i have done is to make it a generic approach, I have created one more file.txt in which i have specified all the identifiers with the table names. and stored it into a dictionary of string, string.
So, I have example some thing like below in my dictionary:
Table Identifier, Table Name
Table Identifier, Table Name
Then I created another dictionary of string as key (Note: I have used the previous dictionary value as a key into this dictionary) and list of string as values to get the column names of the table name.
So, No I have some thing like this below sample data into my dictionary:
Table Name, Column Names IEnumerable
Table Name, Column Names IEnumerable
Then,
The datafile.txt which contains the data as pipe delimited, I split them and saved into a List of KVP of string and List of String. As I mentioned before, I have table identifiers in my data files. So i used them as key in my KVP and store the split values into List of string.
So, No I have some thing like this below sample data into my List of KVP of string , List of string:
Table Identifier, IEnumerable Values
Table Identifier, IEnumerable Values
Now doing half of the work, I am stuck into my FINAL ISSUE:
Now I have All the identifers , Table Names, Column Names and Values with me into the dictionary and List. And only thing to do is to match and merge the records and DUMP it!
For matching: I have thought to match the List of KVPs key with the dictionarys key and then use the values as a key to get the Column Names.
Expected Scenario Image:
List [[List< Column Names>] , [List of String Values]]
MY CODE:
DataTable dt = null;
SqlConnection cn = null;
SqlDataReader dataReader = null;
SqlBulkCopy bulkInsert = null;
StreamReader reader = null;
string path = string.Empty;
public void test()
{
string TableIdentiferFilepath = HttpContext.Current.Server.MapPath("/testfile/TableIdentifer.txt");
Dictionary<string, string> TableIdentifer_TableName = null;
Dictionary<string, List<string>> Table_Name_ColumnName = null;
using (reader = new StreamReader(TableIdentiferFilepath))
{
TableIdentifer_TableName = new Dictionary<string, string>();
Table_Name_ColumnName = new Dictionary<string, List<string>>();
while (!reader.EndOfStream)
{
string[] curr = reader.ReadLine().Split(new string[] { ",", "\r\n" }, StringSplitOptions.None);
TableIdentifer_TableName.Add(curr[0], curr[1]);
using (cn = new SqlConnection(ConString.Connection.conn))
{
cn.Open();
if (cn.State == ConnectionState.Open)
{
string query = string.Format("select column_name from information_schema.columns where table_name = '{0}' order by ordinal_position", curr[1].ToString());
using (SqlCommand cmd = new SqlCommand(query))
{
using (SqlDataAdapter da = new SqlDataAdapter(query, cn))
{
using (dt = new DataTable())
{
da.Fill(dt);
List<string> dataColumns = dt.AsEnumerable().Select(r => r.Field<string>("column_name")).ToList();
Table_Name_ColumnName.Add(curr[1], dataColumns);
}
}
}
}
}
}
}
string path = HttpContext.Current.Server.MapPath("/TextFile/DataSample.txt");
List<KeyValuePair<string, List<string>>> KVPValues = new List<KeyValuePair<string, List<string>>>();
using (reader = new StreamReader(path))
{
while (!reader.EndOfStream)
{
string[] arr = reader.ReadLine().Split(new string[] { "|", "\r\n" }, StringSplitOptions.None);
var collValues = new List<string>();
KVPValues.Add(new KeyValuePair<string, List<string>>(arr[0], arr.Skip(1).AsEnumerable().ToList()));
foreach (var item in TableIdentifer_TableName)
{
foreach (var item2 in Table_Name_ColumnName.Where(c => c.Key == item.Value))
{
var curr_val = item2.Value;
var currKey = KVPValues.Where(p => p.Key == item.Key).ToList();
}
}
}
}
}
This is a BIG PICTURE! Hopefully now people will understand what i want to achieve.
I want to fetch all the column names for specific table..
I am using msaccess and C# .net 2008.
You can fetch schema information for a given query through OleDb using the SchemaOnly CommandBehavior and the GetSchemaTable method, as follows:
var conStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=NWIND.mdb";
using (var con = new OleDbConnection(conStr))
{
con.Open();
using (var cmd = new OleDbCommand("select * from Suppliers", con))
using (var reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly))
{
var table = reader.GetSchemaTable();
var nameCol = table.Columns["ColumnName"];
foreach (DataRow row in table.Rows)
{
Console.WriteLine(row[nameCol]);
}
}
}
A variant of bubi's method for a specific table:
public List<string> GetTableColumnNames(string tableName)
{
var conStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=NWIND.mdb";
using (var connection = new OleDbConnection(conStr))
{
connection.Open();
var schemaTable = connection.GetOleDbSchemaTable(
OleDbSchemaGuid.Columns,
new Object[] { null, null, tableName });
if (schemaTable == null)
return null;
var columnOrdinalForName = schemaTable.Columns["COLUMN_NAME"].Ordinal;
return (from DataRow r in schemaTable.Rows select r.ItemArray[columnOrdinalForName].ToString()).ToList();
}
}
Of course first you might want to check if the table actually exists before getting its column names:
public bool TableExists(string tableName)
{
var conStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=NWIND.mdb";
using (var connection = new OleDbConnection(conStr))
{
connection.Open();
var tables = connection.GetSchema("Tables");
var tableExists = false;
for (var i = 0; i < tables.Rows.Count; i++)
{
tableExists = String.Equals(tables.Rows[i][2].ToString(),
tableName,
StringComparison.CurrentCultureIgnoreCase);
if (tableExists)
break;
}
return tableExists;
}
}
This retrieves all the columns of all tables and views
DataTable schemaTable = ((OleDbConnection)jetConnection).GetOleDbSchemaTable(
System.Data.OleDb.OleDbSchemaGuid.Columns,
new object[] { null, null, null, null });
I found this article while trying to build a C# application to migrate an Access database. The database I'm migrating is an Access 2007/2010 file with .accdb extension.
If you use this code on a table that has Memo or Attachment columns (available in accdb files), it will return the type of these columns as string (wchar).
I had trouble finding much information about how to deal with these types of columns, so I wanted to provide a link to the article that helped me figure out how to handle them:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/d15606f9-f38d-4a1b-8ce3-000c558e79c5
I took the bottom example in that thread and converted it to C#. I did have to add this using statement to the module to avoid having to edit all of the references to "AccessDao":
using AccessDao = Microsoft.Office.Interop.Access.Dao;
My apologies for tacking onto an old thread, but I used this thread as a starting point for writing my code and didn't realize this gotcha right away.
Here's code to get the column names in the order they appear in the Access table. The examples in the other answers here return the column names in alphabetical order (at least for me... using the Microsoft Access Database Engine 2016 Redistributable and .NET Core 3.1).
Based on qnaninf's code example:
var schemaTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, tableName });
var columnOrdinalForName = schemaTable.Columns["COLUMN_NAME"].Ordinal;
var columnOrdinalForOrdinal = schemaTable.Columns["ORDINAL_POSITION"].Ordinal;
var rows = schemaTable.Rows;
var columns = from DataRow r in schemaTable.Rows
orderby r.ItemArray[columnOrdinalForOrdinal]
select new
{
Ordinal = r.ItemArray[columnOrdinalForOrdinal].ToString(),
ColumnName = r.ItemArray[columnOrdinalForName].ToString()
};
You can get the column names in Vb.net and Oledb from MS access database as follows.
'In Vb.net with OleDb
Dim adapter As new OleDb.OleDbDataAdapter
Dim ds As New DataSet
cmd.CommandText = "select * from table_name where 1=2"
adapter.SelectCommand = cmd
adapter.Fill(ds)
adapter.Dispose()
cmd.Dispose()
For Each dr In ds.Tables(0).Columns
ComboBox1.Items.Add(dr.ToString) 'The Column name will come in this combobox
Next