i have a query to delete cascade, here the query
create table satuan_type
(
id int identity(1,1),
satuan_id int(200),
type_id int,
primary key(id),
foreign key(satuan_id) references satuan(id) on update cascade on delete cascade
);
the question is, how to create / add, delete and update cascade with c#?. so the query is running/crete automatically in this method
Dictionary<String, String> dic = new Dictionary<string, string>();
dic.Add("id", "INT PRIMARY KEY IDENTITY");
dic.Add("satuan_id", "INT");
dic.Add("type_id", "INT");
cDatabaseSQLServer.CreateTables("satuan_type", dic);
public int CreateTables(String tableName, Dictionary<String, String> data)
{
switch (sqlType)
{
case DATABASE_SQL_TYPE.DATABASE_SQL_TYPE_SQLITE:
return cSQLite.CreateTables(tableName, data);
case DATABASE_SQL_TYPE.DATABASE_SQL_TYPE_MSSQL:
return cSQL.CreateTables(tableName, data);
}
return 0;
}
public int CreateTables(String tableName, Dictionary<String, String> data)
{
string s = "CREATE TABLE " + tableName + " (";
bool first = true;
foreach (KeyValuePair<String, String> val in data)
{
if (first)
{
first = false;
}
else
{
s = s + ",";
}
string s1;
s1 = String.Format("{0} {1}", val.Key, val.Value);
s = s + s1;
}
s = s + ")";
return this.ExecuteNonQuery(s);
}
I think you need to add logic to your CreateTables-method. Preferably you add more parameters in which you can input any keys that you want constraints on. Cause from what I'm reading at the moment, you are not creating any constraints at all. This is possible by iterating the same logic you've already used, but for primary and foreign keys respectively - preferable with a boolean variable-flag to mark if they should be cascaded or not.
Although, I suggest you do as MSI suggested and use an ORM.
Related
Question is how can I get only the values from my dictionary that contains one key but has a list of values assigned to it. I want to be able to grab all of the values and convert them into a tuple. Any help would be greatly appreciated.
Main code
private static Dictionary<string, List<string>> v_dict_info = new Dictionary<string, List<string>>();
public static Dictionary<string, List<string>> V_dict_info
{
get => v_dict_info;
set => v_dict_info = value;
}
public static string Vista_con_s
{
get => _vista_con_s;
set => _vista_con_s = value;
}
public void get_emp_info_addr()
{
string info_addr = "select " +
"c.empno " +
"from " +
"[V4].[dbo].[person] c ";
try
{
vista_conn = new SqlConnection();
vista_conn.ConnectionString = _vista_con_s;
vista_command = new SqlCommand(info_addr, vista_conn);
vista_conn.Open();
vista_reader = vista_command.ExecuteReader();
if (vista_reader.HasRows)
{
while (vista_reader.Read())
{
v_dict_info.Vista_addr_list("empno", vista_reader.GetValue(0).ToString());
}
}
}
catch (SqlException sq_x)
{
System.Diagnostics.Debug.WriteLine("Error connecting to the database! -Error Msg: {0}", sq_x.ToString());
}
var count = v_dict_info["empno"].Count;
for (int i = 0; i < count; i++)
{
var empno = v_dict_info["empno"][i];
Console.WriteLine("{0}", empno);
}
// how can I get only the values associated to "empno" key
var xx = empno //this only return the first element :( I want all of them
Console.WriteLine(xx.ToString());
}
Here is my method for adding multiple values to one key in a dictionary.
public static class Multi_dict
{
public static void Vista_addr_list<T, U>(this IDictionary<T, List<U>> dict, T key, U elementToList)
{
List<U> list;
bool exists = dict.TryGetValue(key, out list);
if (exists)
{
dict[key].Add(elementToList);
}
else
{
dict[key] = new List<U>();
dict[key].Add(elementToList);
}
}
Presuming this is really necessary (and I agree with Gusman's comment on the question - I don't think this is really what you need), you're already half-way there.
Access the list via the key, and then select out your tuple:
dict[key].Select(x => new Tuple<string, string>(key, x));
You can find a working fiddle here: https://dotnetfiddle.net/jPX0bU
I'm trying to make a utility to generate an insert script of SQL tables along with relational table.
I got all the values in C#.
Now I want to remove the one column name and its value from the script.most probably the identity column.
For example: the string I have (which keeps on changing with table name and varies)
INSERT INTO Core.Customers ([customerId], [customername], [customeradress],[ordernumber])
VALUES (123, N'Rahul', N'244 LIZ MORN', 2334)
NOW I know I have to remove CustomerId (sometimes need to be replaces with #somevariable).
Please give me an efficient way how to retrieve customerId value and deleting column name and value.
I was looking for a method to find column value by column Name.
What I am doing is below - I know it's inefficient and can cause problem but for now it is working smoothly.
public string GetColumnValueToForDesiredColumnName(string row, TableInfo tableinfo, string NameofColumnTOfindvalueFor)
{
Dictionary<string, string> ValueTypedictionary = new Dictionary<string, string>();
string value = null;
// this code is quite messy - I need some suggestion on this one
string[] plusseperatedinsert = row.Replace("INSERT " + "[" + tableinfo.Schema + "].[" + tableinfo.TableName + "]", string.Empty).Trim().Replace("VALUES", "+").Split('+');
string[] columnvalues = plusseperatedinsert[0].Replace("(", string.Empty).Replace(")", string.Empty).Replace("(", string.Empty).Replace("[", string.Empty).Replace("]", string.Empty).Trim().Split(',');
string[] valuesfield = plusseperatedinsert[1].Replace("(", string.Empty).Replace(")", string.Empty).Replace("(", string.Empty).Replace("[", string.Empty).Replace("]", string.Empty).Trim().Split(',');
for (int index = 0; index < columnvalues.Length; index++)
{
ValueTypedictionary.Add(columnvalues[index], valuesfield[index]);
}
ValueTypedictionary.TryGetValue(NameofColumnTOfindvalueFor, out value);
return value;
}
This returns 123 as value.
And then I am using
string.Replace("[customerId],", string.empty).Replace(123, string.empty);
Create a special clas InsertQuery which stores pairs of column names with column values and then if you always need to remove or change an Id of a table you will know that it is on the first index of a list/array/whatever you use to store these pairs.
Define a method for removing this column and you are good to go.
So here is the code. You will probably change it somehow, it is just a proof of concept.
public class InsertQuery
{
private class Column
{
public string Name { get; set; }
public string Value { get; set; }
}
private readonly List<Column> columns = new List<Column>();
private readonly string tableName;
public InsertQuery(string tableName)
{
this.tableName = tableName;
}
public void AddColumn(string name, string value)
{
columns.Add(new Column { Name = name, Value = value });
}
public string RemoveColumnByName(string columnName)
{
var column = columns.First(c => c.Name == columnName);
var value = column.Value;
columns.Remove(column);
return value;
}
public string RemoveIdColumn()
{
var column = columns.First();
var value = column.Value;
columns.RemoveAt(0);
return value;
}
public override string ToString()
{
var sb = new StringBuilder();
sb.Append("INSERT INTO ");
sb.Append(tableName);
sb.Append(" (");
// append first all column names and then their values
return sb.ToString();
}
}
Trust me. Building such a tool using just string operations is not quite a good idea. In time you will want to add more functionality and you will be stuck with code that can be hardly extended. Encapsulation is a way to go.
I have the code below which is intended to build a dictionary object with the following construction Dictionary<string<Dictionary<string, string>. For some reason each time I add an item to it the key text is correct but the value (dictionary) overwrites the previous one. This is probably better explained like this:
Iteration 1
key1, dictionary1
Iteration 2
key1, dictionary2
key2, dictionary2
Iteration 3
key1, dictionary3
key2, dictionary3
key3, dictionary3
What is causing this and how can I fix this code to stop it overwriting the dictionary in each entry?
QueryNameUserQueryString = new Dictionary<string, string>();
DialectDictionary = new Dictionary<string, Dictionary<string, string>>();
while (dataBaseConnection.NextRecord())
{
if (QueryNameUserQueryString != null)
{
QueryNameUserQueryString.Clear();
}
string dialect = dataBaseConnection.GetFieldById (0);
//If no dialect then carry out next iteration
if (String.IsNullOrEmpty (dialect))
{
continue;
}
try
{
dataBaseConnection2.ExecutePureSqlQuery ("SELECT * FROM " + sqlFactoryTable + " WHERE SQL_FACTORY_DIALECT = '" + dialect + "'");
}
catch
{
dataBaseConnection.Close();
dataBaseConnection2.Close();
throw;
}
//Do we have query strings for this dialect?
if (!dataBaseConnection2.HasRows())
{
continue;
}
//loop through query strings
while (dataBaseConnection2.NextRecord())
{
string queryName = dataBaseConnection2.GetFieldById (2);
string queryString = dataBaseConnection2.GetFieldById (3);
string user = dataBaseConnection2.GetFieldById (4);
//create composite key for dictionary
string compositeKey = dialect + "," + queryName + "," + user;
if (QueryNameUserQueryString != null)
{
//Construct our query string dictionary
QueryNameUserQueryString.Add (compositeKey, queryString);
}
}
//If we have a query string dictionary
if (QueryNameUserQueryString != null)
{
//Ensure m_dialect dictionary is not null
if (DialectDictionary != null)
{
//Construct our dictionary entry for this dialect
DialectDictionary.Add (dialect, QueryNameUserQueryString);
}
}
}
}
You seem to be using the same instance of QueryNameUserQueryString on every iteration. When it's added to the DialectDictionary, it's added as a reference - not a copy of the original.
To "properly" solve the issue, I would move the declaration of your QueryNameUserQueryString variable inside the while-scope. That way you would make sure that it can only exist in the scope of a single iteration, not across several. When it's added to the DialectDictionary, the reference lives on in that dictionary and you're safe to leave the scope.
You are using same instance of QueryNameUserQueryString everytime. Replace
QueryNameUserQueryString.Clear();
with
QueryNameUserQueryString = new Dictionary<string, string>();
public static string filename2_1, filename2_2, filename2_3;
filename2_1="xyz.jpg";
filename2_2="abc.png";
filename2_3="qwe.jpg";
.....
...
for (int key = 1; key <= 3; key++)
{
....
foreach (var item in tabItem)
{
item.ImagePath.Value = "images1/" + ("filename2_" + key);
item.ThumbPath.Value = "thumbnails1/" + ("filename2_" + key);
}
}
As stated above I need to convert ("filename2_" + key) into actual variable. Can anyone help me regarding this
You can't have dynamic variable names.
Variable names cannot be "created".
You can use an array or a generic collection to hold the collections of data you are using.
var fileSuffixList = new List<string>{ "xyz.jpg" , "abc.png", "qwe.jpg"};
foreach(string fileSuffix in fileSuffixList)
{
....
foreach (var item in tabItem)
{
item.ImagePath.Value = "images1/" + ("filename2_" + fileSuffix);
item.ThumbPath.Value = "thumbnails1/" + ("filename2_" + fileSuffix);
}
}
As #Oded stated, you can't have dynamic variable names.
What you can do is use a Collection such as a dictionary:
Dictionary<string, int> dictionary = new Dictionary<string, string>();
dictionary.Add("filename2_" + key, "Value");
If your keys are always numeric, you can also use an array or a List. However, without more information, it's hard to tell you the best way to go about it.
Q:
When i try to execute the following parametrized query:
INSERT INTO days (day,short,name,depcode,studycode,batchnum) values (?,?,?,?,?,?);SELECT SCOPE_IDENTITY();
through command.ExecuteScalar();
throws the following exception:
ERROR [07001] [Informix .NET provider]Wrong number of parameters.
Where is the problem?
EDIT:
public static int InsertDays(List<Day> days)
{
int affectedRow = -1;
Dictionary<string, string> daysParameter = new Dictionary<string, string>();
try
{
foreach (Day a in days)
{
daysParameter.Add("day", a.DayId.ToString());
daysParameter.Add("short", a.ShortName);
daysParameter.Add("name", a.Name);
daysParameter.Add("depcode", a.DepCode.ToString());
daysParameter.Add("studycode", a.StudyCode.ToString());
daysParameter.Add("batchnum", a.BatchNum.ToString());
affectedRow = DBUtilities.InsertEntity_Return_ID("days", daysParameter);
daysParameter.Clear();
if (affectedRow < 0)
{
break;
}
}
}
catch (Exception ee)
{
string message = ee.Message;
}
return affectedRow;
}
public static int InsertEntity_Return_ID(string tblName, Dictionary<string, string> dtParams)
{
int Result = -1;
DBConnectionForInformix DAL_Helper = new DBConnectionForInformix("");
string[] field_names = new string[dtParams.Count];
dtParams.Keys.CopyTo(field_names, 0);
string[] field_values = new string[dtParams.Count];
string[] field_valuesParam = new string[dtParams.Count];
dtParams.Values.CopyTo(field_values, 0);
for (int i = 0; i < field_names.Length; i++)
{
field_valuesParam[i] = "?";
}
string insertCmd = #"INSERT INTO " + tblName + " (" + string.Join(",", field_names) + ") values (" + string.Join(",", field_valuesParam) + ");SELECT SCOPE_IDENTITY();";
Result = int.Parse(DAL_Helper.Return_Scalar(insertCmd));
return Result;
}
You haven't shown where you're actually populating the parameter values. Given that you've got the right number of question marks, I suspect that's where the problem lies.
EDIT: Okay, now you've posted more code, it's obvious what's going wrong: your Return_Scalar method isn't accepting any actual values! You're not using field_values anywhere after populating it. You need to set the parameters in the command.
(You should also look at .NET naming conventions, by the way...)
Ensure that where you are providing the parameters that one of the values is not null. That may cause the provider to ignore the parameter. If this is your issue pass DBNull.
EDIT
As Jon stated you need to use command.Parameters to give the command the parameters to use in the query.