Return Distinct Rows in the Web API - c#

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

Related

how to write query in ado.net consist of data dictionary

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());

LINQ query not showing results - LEFT join with WHERE clause

This is my first foray into LINQ.
I still have to wrap my head around the results part, but I can't seem to get any results from this.
var institutions = from lots in lotsdb.NEWinstitution
join webs in webbitdb.tblinstitution
on lots.institutionid equals webs.dispenseinstid into newinsts
from webs2 in newinsts.DefaultIfEmpty()
where webs2 == null
select new
{
instid = lots.institutionid,
instname = lots.institutionname
};
foreach(var instfound in institutions)
{
MessageBox.Show(instfound.instid.ToString() + " " + instfound.instname.ToString());
}
I'm using Datasets created by Visual Studio in the DATASources list.
Below is my original SQL string that i have "tried" to adapt to LINQ
string strgetloc = #"
SELECT NEWinstitution.institutionid, NEWinstitution.institutionname
FROM NEWinstitution
LEFT JOIN tblinstitution
ON NEWinstitution.institutionid = tblinstitution.dispenseinstid
WHERE (((tblinstitution.institutionid) Is Null));"
You probably need something like this:
var institutions =
from lots in lotsdb.NEWinstitution
join webs in webbitdb.tblinstitution on lots.institutionid equals webs.dispenseinstid
where webs.IsInstitutionIdNull()
select new
{
instid = lots.institutionid,
instname = lots.institutionname
};
The IsInstitutionIdNull() method is generated by the MSDataSetGenerator when the columns allows DBNull. Because you cannot compare it directly to DBNull or to null.
(fixed a typo)
So I ended up using the following code:
var idsNotInB = dtLotsInst.AsEnumerable().Select(r => r.Field<int>("institutionid"))
.Except(dtWebbitInst.AsEnumerable().Select(r => r.Field<int>("institutionid")));
count = idsNotInB.Count();
if (count != 0)
{
DataTable dtOnlyLots = (from row in dtLotsInst.AsEnumerable()
join id in idsNotInB
on row.Field<int>("institutionid") equals id
select row).CopyToDataTable();
using (OleDbConnection con = new OleDbConnection(PackChecker.Properties.Settings.Default["WebbitConnectionString"].ToString()))
{
string strgetloc = #"INSERT INTO tblinstitution ( dispenseinstid, institutionname ) VALUES (?,?)";
using (OleDbCommand cmd = new OleDbCommand(strgetloc, con))
{
con.Open();
foreach (DataRow dr in dtOnlyLots.Rows)
{
cmd.Parameters.Add("?", OleDbType.Integer).Value = Convert.ToInt32(dr["institutionid"]);
cmd.Parameters.Add("?", OleDbType.VarWChar).Value = dr["institutionname"].ToString();
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
con.Close();
}
}
}
This uses LINQ and works well by using "EXCEPT" in the first LINQ section to find values not in one table. Then it uses this list to generate the rows from the table I want.

Remove decimals from listview subitem

My listview is being populated by a sql query. The data on sql is an integer "25, 4, 9" etc. But when added to listview its "25.000, 4.000" etc. I've tried using the ("0.#") format but it just tells me it cannot convert to integer. The subitem I'm having the issue with is [VOID_LENGTH]
foreach (Dictionary<string, string> d in resultHistory)
{
ListViewItem lvi = new ListViewItem(d["LOT_NO"]);
lvi.SubItems.Add(d["SERIAL_NO"]);
lvi.SubItems.Add(d["DATE_TIME"]);
lvi.SubItems.Add(d["VOID_LOC"]);
lvi.SubItems.Add(d["VOID_LENGTH"]);
lvi.SubItems.Add(d["EMPL_ID"]);
listView1.Items.Add(lvi);
}
The query
public List<Dictionary<string, string>> GetVoid(string VoidDate, bool orderByDate = false)
{
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
string query = "";
List<OleDbParameter> queryParameters = new List<OleDbParameter>();
query = "SELECT LOT_NO, SERIAL_NO, DATE_TIME, VOID_LOC, VOID_LENGTH, EMPL_ID ";
query += "FROM MPCS.BRAZE_VOIDS ";
query += "WHERE TRUNC(DATE_TIME) = TO_DATE(?, 'dd-MON-yy')";
if (orderByDate)
{
query += " order by INS_UPD_TIMESTAMP asc, VOID_LOC desc";
}
queryParameters.Add(new OleDbParameter("DATE_TIME", VoidDate));
results = this.ExecuteParameterQuery(query, queryParameters);
return (results);
}
Your column type in DB is decimal(n,3) I think, you can cast it into int while select. Modify select query part like this
cast(VOID_LENGTH as int) as VOID_LENGTH

SQL Bulk Copy into separate Tables

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.

Get column name from SQL Server

I'm trying to get the column names of a table I have stored in SQL Server 2008 R2.
I've literally tried everything but I can't seem to find how to do this.
Right now this is my code in C#
public string[] getColumnsName()
{
List<string> listacolumnas=new List<string>();
using (SqlConnection connection = new SqlConnection(Connection))
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT TOP 0 * FROM Usuarios";
connection.Open();
using (var reader = command.ExecuteReader(CommandBehavior.KeyInfo))
{
reader.Read();
var table = reader.GetSchemaTable();
foreach (DataColumn column in table.Columns)
{
listacolumnas.Add(column.ColumnName);
}
}
}
return listacolumnas.ToArray();
}
But this is returning me the following
<string>ColumnName</string>
<string>ColumnOrdinal</string>
<string>ColumnSize</string>
<string>NumericPrecision</string>
<string>NumericScale</string>
<string>IsUnique</string>
<string>IsKey</string>
<string>BaseServerName</string>
<string>BaseCatalogName</string>
<string>BaseColumnName</string>
<string>BaseSchemaName</string>
<string>BaseTableName</string>
<string>DataType</string>
<string>AllowDBNull</string>
<string>ProviderType</string>
<string>IsAliased</string>
<string>IsExpression</string>
<string>IsIdentity</string>
<string>IsAutoIncrement</string>
<string>IsRowVersion</string>
<string>IsHidden</string>
<string>IsLong</string>
<string>IsReadOnly</string>
<string>ProviderSpecificDataType</string>
<string>DataTypeName</string>
<string>XmlSchemaCollectionDatabase</string>
<string>XmlSchemaCollectionOwningSchema</string>
<string>XmlSchemaCollectionName</string>
<string>UdtAssemblyQualifiedName</string>
<string>NonVersionedProviderType</string>
<string>IsColumnSet</string>
Any ideas?
It shows the <string> tags as this is how my web service sends the data.
You can use the query below to get the column names for your table. The query below gets all the columns for a user table of a given name:
select c.name from sys.columns c
inner join sys.tables t
on t.object_id = c.object_id
and t.name = 'Usuarios' and t.type = 'U'
In your code, it will look like that:
public string[] getColumnsName()
{
List<string> listacolumnas=new List<string>();
using (SqlConnection connection = new SqlConnection(Connection))
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "select c.name from sys.columns c inner join sys.tables t on t.object_id = c.object_id and t.name = 'Usuarios' and t.type = 'U'";
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
listacolumnas.Add(reader.GetString(0));
}
}
}
return listacolumnas.ToArray();
}
I typically use the GetSchema method to retrieve Column specific information, this snippet will return the column names in a string List:
using (SqlConnection conn = new SqlConnection("<ConnectionString>"))
{
string[] restrictions = new string[4] { null, null, "<TableName>", null };
conn.Open();
var columnList = conn.GetSchema("Columns", restrictions).AsEnumerable().Select(s => s.Field<String>("Column_Name")).ToList();
}
SELECT COLUMN_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = 'YourTable'
public string[] getColumnsName()
{
List<string> listacolumnas=new List<string>();
using (SqlConnection connection = new SqlConnection(Connection))
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "select column_name from information_schema.columns where table_name = 'Usuarios'";
connection.Open(;
using (var reader = command.ExecuteReader(CommandBehavior.KeyInfo))
{
reader.Read();
var table = reader.GetSchemaTable();
foreach (DataColumn column in table.Columns)
{
listacolumnas.Add(column.ColumnName);
}
}
}
return listacolumnas.ToArray();
}
The original post was close to the goal, Just some small changes and you got it.
Here is my solution.
public List<string> GetColumns(string tableName)
{
List<string> colList = new List<string>();
DataTable dataTable = new DataTable();
string cmdString = String.Format("SELECT TOP 0 * FROM {0}", tableName);
if (ConnectionManager != null)
{
try
{
using (SqlDataAdapter dataContent = new SqlDataAdapter(cmdString, ConnectionManager.ConnectionToSQL))
{
dataContent.Fill(dataTable);
foreach (DataColumn col in dataTable.Columns)
{
colList.Add(col.ColumnName);
}
}
}
catch (Exception ex)
{
InternalError = ex.Message;
}
}
return colList;
}
Currently, there are two ways I could think of doing this:
In pure SQL Server SQL you can use the views defined in INFORMATION_SCHEMA.COLUMNS. There, you would need to select the row for your table, matching on the column TABLE_NAME.
Since you are using C#, it's probably easier to obtain the names from the SqlDataReader instance that is returned by ExecuteReader. The class provides a property FieldCount, for the number of columns, and a method GetName(int), taking the column number as its argument and returning the name of the column.
sp_columns - http://technet.microsoft.com/en-us/library/ms176077.aspx
There are many built in stored procedures for this type of thing.

Categories

Resources