I am trying to create a web service, with C# and Visual Studio 2010, that will insert values form a view table into another table using a SQL query. In the past we have used this type of service but we have asked the user to enter the values they want to update, but with the query I am using there is no need for user input since the values will be inserted only when one of the field values is NULL.
Below is the code I been trying to use, I adapted the code we used before, but in here I am still expecting user input. How can I update my code as to not expect the input. I know I can just run this query from MySQL but I want be able to create a button in our site so other people can do it. Here is the code that runs the query:
public void AddUsers(string json)
{
GetDbInstance();
var sql = "insert into dbo.ASPECTS_users_activity " +
"(user_id, usr_address, usr_phone, usr_email, usr_website, usr_photo ) " +
"select #v.customer_id, #usr_address, #usr_phone, #usr_email, #usr_website, #usr_photo " +
"from dbo.ASPECTS_current_users_vw v where usr_photo is NULL;";
var usrInformation = JsonConvert.DeserializeObject<UpdateExhibitors>(json);
Console.WriteLine(usrInformation);
var conn = db.Connection();
try
{
SqlCommand command = new SqlCommand(sql, conn);
command.Parameters.AddWithValue("#v.customer_id", usrInformation.master_customer_id);
command.Parameters.AddWithValue("#usr_address", "123 XYZ Post, Columbus, IN");
command.Parameters.AddWithValue("#usr_phone", "555-555-5555");
command.Parameters.AddWithValue("#usr_email", "test#sample.com");
command.Parameters.AddWithValue("#usr_website", "http://www.sample.com");
command.Parameters.AddWithValue("#usr_photo", "");
command.ExecuteNonQuery();
command.Dispose();
command = null;
}
catch (Exception e)
{
throw new Exception(e.ToString(), e);
}
finally
{
conn.Close();
}
}
Here is the Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Customer_Insert.Models {
public class AddUsers {
public string customer_id { get; set; }
public string usr_address { get; set; }
public string usr_phone { get; set; }
public string usr_email { get; set; }
public string usr_website { get; set; }
public string usr_photo { get; set; }
}
}
Just so you know the only field that will be populated from the view to will be the customer_id field, all the other fields will have default values, which will be updated at another point. Not many people here know SQL so creating this option will provide an option if I am not around.
Since you "can just run this query from MySQL", I would save that query as a Stored Procedure in your database. Then you need neither SQL nor parameters in your code.
SqlCommand command = new SqlCommand("yourStoredProcedureName", conn);
command.ExecuteNonQuery();
...
Related
First of all, I have seen this post: Raw SQL Query without DbSet - Entity Framework Core but I feel like it does not answer my question.
I have an ASP.NET Core MVC project with Entity Framework Core (newest at this date).
What I need to do is:
public IActionResult MyView(string NameOfTable)
{
// send model that is same as NameOfTable
// or
// send something like List<string> that has properties and names of columns
return View();
}
What I want to do is call a function and send the name of a table in database. It will find the table in the database and return the properties of table (column names, types of columns[int/ varchar..]).
What I think will work: either write raw SQL to database.
What I think is good answer: some snippet of how to write raw SQL to query the database without knowing a model. Or some way of overcoming this problem.
Thanks for everything. Sorry if this is dumb question.
Sorry for bothering you all. I have found solution. Here it is:
public class AA
{
public string One { get; set; }
public string Two { get; set; }
}
private async Task pokus()
{
List<AA> groups = new List<AA>();
var conn = _db.Database.GetDbConnection();
try
{
await conn.OpenAsync();
using (var command = conn.CreateCommand())
{
string query = "SELECT * FROM TABLE";
command.CommandText = query;
DbDataReader reader = await command.ExecuteReaderAsync();
if (reader.HasRows)
{
while (await reader.ReadAsync())
{
try
{
var row = new AA { One = reader.GetString(1), Two = reader.GetString(2) };
groups.Add(row);
}
catch { }
}
}
else
{
Console.WriteLine("Dont have rows");
}
reader.Dispose();
}
}
finally
{
conn.Close();
}
foreach(AA s in groups)
{
Console.WriteLine(s.One);
Console.WriteLine(s.Two);
}
}
I hope it will help somebody.
I want (When Button Clicked) previous row still exist in datagridview while adding new row (such that user can add as many rows as he/she want at runtime in datagridview).
I found many questions on stackoverflow.com regarding rows of datagridview but i cannot figure out them according to my problem. Second, i am new in Dapper and all answers using ADO.NET.
I have an idea that there should be an easy way of such problem.
I bind my datagridview to Orders Class.
Here is my Orders class...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test
{
public class Orders
{
public int ItemId { get; set; }
public string ItemName { get; set; }
public string Brand { get; set; }
public string Category { get; set; }
public int Quantity { get; set; }
public int Price { get; set; }
}
}
Select Button Click Event is..
private void btn_select_Click(object sender, EventArgs e)
{
using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["Connection"].ConnectionString))
{
if (db.State == ConnectionState.Closed)
db.Open();
string query = "SELECT *FROM tbl_ItemDetail WHERE ItemName=#ItemName";
ordersBindingSource.DataSource = db.Query<Orders>(query, new { ItemName = txt_sell_item.Text });
}
}
When I enter ItemName as 'bread' then GUI is..
But when I enter ItemName as 'bjn' then first row replaces with newest row..
The main reason behind your problem lies within your button click event handler, You are binding DataSource every time the user clicks the button which gives you one record as expected. Instead of assigning DataSource, write a insert statement which inserts record within your grid. By doing this, your issue will be surely resolved.
I'm not giving solution with code because I don't have my pc right now.
I'm trying to use PetaPoco ORM to get data from MySQL table. Below is the sample code to get only one record:
public void ShowEmployerDetails()
{
using (var db = new PetaPoco.Database ("mysql_mydb")) {
try {
var employers = db.Query <Employers> ("SELECT * FROM Employer WHERE id = 123456789");
foreach(var e in employers) {
return e.EmployerName;
}
} catch (Exception ex) {
log.Error (ex.Message);
}
}
}
There is need to pass the entity type in db.Query function. For each DB table, we need to define entities. In this case, the entity type is <Employers> and code is as:
public class Employers
{
public int id { get; set; }
public string EmployerName { get; set; }
}
Is there any way that we can generalize the above select query also? For instance, I'm planning to get output using single query like:
PetaPocoQueryEntities <Employers>.GetDataFromEntities ("SELECT * FROM Employer WHERE id = 123456789", "EmployerName");
And the query could be something like below where entity type could be passed as generic type T and wonder if there is some way in providing column name and getting column value dynamically:
public static class PetaPocoQueryEntities <T>
{
public static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public static T GetDataFromEntity (string sqlQuery, string colName )
{
using (var db = new PetaPoco.Database ("mysql_mydb")) {
try {
var entityResults = db.Query<T> (sqlQuery);
foreach (var result in entityResults) {
log.Info(colName + " value is " + result.colName);
}
} catch (Exception ex) {
log.Error (ex.Message);
}
return colName;
}
}
}
Please help.
There is need to pass the entity type in db.Query function
Short answer - yes. PetaPoco uses this information to map the data from the query back to entity correctly
Is there any way that we can generalize the above select query also? For instance, I'm planning to get output using single query like:
Yep, you could rig this up. This integration test should get you started.
I tried to find a solution for this but couldn't. Here's the problem:
I'm loading data of a bunch of users and creating an object for each user. Each user object has many object properties. Here's the structure:
public class User {
public int ID { get; set; }
public string Name { get; set; }
public City City { get; set; }
public Office Office { get; set; }
}
The City class:
public class City {
public int ID { get; set; }
public string Name { get; set; }
public string Keyword { get; set; }
}
The Office class:
public class Office {
public int ID { get; set; }
public string Address { get; set; }
public int CityID { get; set; }
}
The user object has many other similar properties like City & Office which are basically class objects.
Now here's the main issue. Whenever I try to load all the users into a collection of dictionary, StackOverflow exception occurs at SqlCon.Open() (See the "Fetch" function I've written below). Here's how I'm loading everything:
//Code to load users
Dictionary<int, User> Users = new Dictionary<int, Users>();
DataTable usersData = new DataTable();
//The Fetch function has two version. The first one; which is mentioned in this post, returns the result as Dictionary<string, object>().
//The second version of the function returns the result in the form of the a DataTable and is only used when multiple rows are required from the database. The following returns a set of rows in a DataTable.
Globals.MainDatabase.Fetch("SELECT * FROM users", out usersData);
foreach (DataRow row in usersData.Rows) {
User user = new User();
user.ID = Convert.ToInt32(row["id"]);
user.Name = row["name"].ToString();
user.City = Cities.Get(Convert.ToInt32(row["city_id"]));
user.Office = Offices.Get(Convert.ToInt32(row["office_id"]));
Users.Add(user.ID, user);
}
The methods "Cities.Get(Int32 id)" and "Offices.Get(Int32 id)" uses the following function to fetch data from the database.
public void Fetch(string query, out Dictionary<string, object> results) {
var dict = new Dictionary<string, object>();
try {
using (SqlConnection SqlCon = new SqlConnection(ConnectionString)) {
using (SqlCmd = new SqlCommand()) {
SqlCmd.Connection = SqlCon;
SqlCmd.CommandType = CommandType.Text;
SqlCmd.CommandText = query;
SqlCon.Open();
DataTable temp = new DataTable();
using (SqlDataAdapter SqlAdp = new SqlDataAdapter(SqlCmd)) {
SqlAdp.SelectCommand = SqlCmd;
SqlAdp.Fill(temp);
}
DataRow row = temp.Rows[0];
temp = null;
dict = row.Table.Columns
.Cast<DataColumn>()
.ToDictionary(col => col.ColumnName, col => row.Field<object>(col.ColumnName));
}
}
}
catch (Exception ex) {
HandleException(ex, "An error occurred when tried to fetch data.", query);
}
results = dict;
dict = null;
}
I realize that this "Fetch" function is being called multiple times when creating the user object. The "StackOverflow" exception occurs exactly at this line:
SqlCon.Open();
How can I solve this error? or probably I should use a better approach to do this?
A bit too long for a comment
Do you really need to load ALL data from the database? It is better to just grab the columns and rows you need.
Why are you copying DataTables in to Dictionaries? What is wrong with just using a DataTable?
99.9% of the time you will have better performance performing JOINs in the database.
Don't try to roll your own 'ORM'. Use something like Dapper if you don't want the bloat of EF or NHibernate. Or, stick to ADO (DataTable, DataAdapter etc.)
using (SqlConnection SqlCon = new SqlConnection(ConnectionString)) {
Is your connection string variable really named ConnectionString? Is it possible you are having a name clash with the type? Since it is not declared in the shown code, I assume it is a class variable, so you should respect the conventional naming convention, which would be _connectionString. What does your connection string look like?
Alright folks, I figured it out. It was all because of faulty architecture of the whole demo application. Some objects have one or more other objects as properties and due to some silly faults in the architecture; the "fetch" operation which serves as the base of fetching data from the database, was recursively called resulting into StackOverflow exception which was actually a large number of database connections being initialized ultimately growing the heap size to an extent which causes the exception.
I tried to summarize everything in the paragraph written above because posting the complete source code is useless considering the large amount of code.
Thank you everyone who helped, especially #Guffa's comment on the main post which forced me to investigate the whole issue from scratch rather than sticking to the exception stack.
I want to retrieve only the first three results of a query and show them in a ListView, but how can I filter my results?
This is my code:
var dbpath = Path.Combine(Windows.ApplicationModel.Package.Current.InstalledLocation.Path, "guessndraw.db");
using (var db = new SQLite.SQLiteConnection(dbpath))
{
ListaParole.ItemsSource = db.Table<wordlist_it>();
}
wordlist_it class:
public class wordlist_it
{
public string word { get; set; }
public override string ToString()
{
return string.Format("{0}",word);
}
}
In this way, it gives me ALL the records of the table, but I just want the first 3 records.
Can you explain me how to set a query in a windows store application using c# and sqlite? Thank you :)
this is from memory, but you could try:
ListaParole.ItemsSource = db.Table<wordlist_it>().Take(3);