i want to run my void method automatically when my project runs but it doesn't. i tried this but i think this is not good way. what is another way or how i can initialize my void method.
string fAccount;
[Key]
[Size(150)]
public string Account
{
get { GroupedAccount(); return fAccount; }
set { SetPropertyValue<string>(nameof(Account), ref fAccount, value); }
}
private void GroupedAccount()
{
SqlConnection conn = new SqlConnection("Connection");
SqlCommand cmd = new SqlCommand("SELECT * FROM Traders", conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
conn.Open();
var groupedData = from b in dt.AsEnumerable()
group b by b.Field<string>("Account Name") into g
select new
{
fAccounts = g.Key,
};
foreach (var r in groupedData)
{
SqlCommand cmd2 = new SqlCommand("INSERT INTO dbo.TradersAccount (Account) VALUES (#Account)", conn);
cmd2.Parameters.AddWithValue("#Account", r.fAccounts);
cmd2.ExecuteNonQuery();
}
conn.Close();
}
In an XAF application, you have several places to put startup code, but in your case it looks like you are trying to initialize some objects in the database based on some existing data. The recommended place for this is the ModuleUpdater in the Updater.cs file. See the documentation for more information:
Create and update the application's database
Supply Initial Data for XPO.
Your Account property is part of an XPO object. XPO is an object relational mapper, that is, it abstracts away the complexities of transferring your C# classes to SQL storage. In general you should refrain from putting any additional code in the getters and setters of persisted properties. The DevExpress documentation is good:
Ways to add a business class
Comprehensive XAF Tutorial.
XPO best practices
In particular, XPO is intended to dispense with the need for direct SQL. If you need TradersAccount objects to be created or updated whenever an Trader object is modified, then you would normally create a TraderAccount XPO object and define an association property and create it with new TraderAccount(Session) and add it to the association property collection. Then XPO will automatically generate all of the corresponding SQL for you.
Related
I am a beginner at C# and .NET oop concepts. I want to load the datagridview. I don't know how to pass the data. What I tried so far I attached below.
I created a class std
public void get()
{
SqlConnection con = new SqlConnection("server =.; initial catalog=testdb; User ID=sa; Password=123");
string sql = "select * from std";
con.Open();
SqlCommand cm = new SqlCommand(sql, con);
SqlDataReader dr = cm.ExecuteReader();
while ( dr.Read())
{
string stname = dr["st_name"].ToString();
string nicnum = dr["nic"].ToString();
}
con.Close();
}
Form: I am getting data like this way
std ss = new std();
ss.get();
dataGridView1.Rows.Clear();
If I wrote like this way how to pass data into the datagridview columns? I am stuck in this area
It's easier like this:
public void FillGrid()
{
var dt = new DataTable();
var da = new SqlDataAdapter("select * from std", "server =.; initial catalog=testdb; User ID=sa; Password=123");
da.Fill(dt);
dataGridView1.DataSource = dt;
}
but if you're going to use such a low level method of database access you should consider adding a DataSet type of file to your project; visual studio will write all this code and more for you with a few mouse clicks, and it makes a good job of creating tables and adapters that are a lot easier to work with
you have made multiple mistakes. First you read data wirh dataraeader and in every iteration define two stname and nimnum variables like. So when loop ends variables are destroyed. You have to define data table and read data by dataraeader and and add them to it row by row. Or read by sqldataadapter and read it immediately and pass to datatable object.Finnaly you pass datatable as return object of function. Use this vala as datasource of datagridview property if I'm not wrong.
All I want to do is a very simple select/picklist with values from a MySQL database.
I'm trying to find a simple solution online (I'm new to C#) and everything I'm finding is very complicated.
All I want to do is generate the <select><option.. etc parts, with all the attributes and values that I want to set.
This seems like it should be very, very easy. Can anyone give me some basic instructions, or point me to a tutorial that shows how to accomplish this?
Currently, I am using MySqlCommand and MySqlDataReader for classes to talk to the database (for another function).
Create a class for the entity you want to display. Ex : If you want to show all states in the dropdown, create State class
public class State
{
public int ID { set;get;}
public string Name { set;get;}
}
Now write a method in which you query the database and get the result to the DataReader, Iterate over the items and set the values a new object of our State class. Add each object to a list (of State class). So your method's return type will be a List of State class object.
public List<State> GetStates()
{
List<State> stateList=new List<State>();
// execute query, read from reader and add to the stateList
// the below code is SqlServer DB specific.
// you need to change the Connection,Command class for it to use with MySql.
using (var con= new SqlConnection("replace your connection string"))
{
string qry="SELECT ID,NAME FROM STATES";
var cmd= new SqlCommand(qry, objConnection);
cmd.CommandType = CommandType.Text;
con.Open();
using (var objReader = cmd.ExecuteReader())
{
if (objReader.HasRows)
{
while (objReader.Read())
{
var item=new State();
item.ID=reader.GetInt32(reader.GetOrdinal("ID"));
item.Name=reader.GetString(reader.GetOrdinal("Name"));
stateList.Add(item);
}
}
}
}
return stateList;
}
Now, have a DropDownList control in your page,
<asp:DropDownList id="states" runat="server" />
Now in the codebehind of this page, you can set the data for the dropdown( possibly in the Page_Load event)
if(!isPostBack)
{
states.DataSource=yourRepositary.GetStates();
states.DataTextField="Name";
states.DataValueField="ID";
states.DataBind();
}
I think what you searching for is something like a DropDownList, it accepts a DataSource, so you can use your already populated MySqlDataReader as it.
Something like this
MySqlDataReader dr = //the code to fill the MySqlDataReader
DropDownList1.DataSource = dr;
You can create the DropDownList in the design of your page.
To show the data you need to set then the values
DropDownList1.DataValueField = "DbField1";
DropDownList1.DataTextField = "DbField2";
Generally, in a list/drop down you got (a) the value that will be selected and (b) its presentation to the user. The first one might be some primary key, the second might be some label which is self-explaining to the user.
Assuming you got a table FOOD like
FoodValue | FoodLabel
---------------
00010 | Sausage
00020 | Eggs
00030 | Cheese
Put a listbox in your ASP.NET view, e.g. listBox1, then
you can read it in the code behind using
MySqlConnection con = new MySqlConnection("YOUR CONNECTION STRING");
MySqlCommand cmd = new MySqlCommand("SELECT FoodValue, FoodLabel FROM FOOD", con);
con.Open();
MySqlDataReader r = cmd.ExecuteReader();
while(r.Read()) {
listBox1.Items.Add(new ListItem(r["FoodLabel"], r["FoodValue"]);
}
con.Close();
But keep in mind this is a quick and dirty approach. In production code, you will need some separation of the presentation and data layer. Use the data source controls to bind your data in a better way.
I need to create an generic data access layer to use in my final assignment in Software Engineering, but my data access layer that I have currently created can automatically generate CRUD(Create, Read, Update and Delete) SQL Statement. I still need to define every table in my database and every time I change my database I need to define the changes in my data access layer.
Please look at the sample of my code and tell me how to change my code to improve my access layer:
class sqlConn
{
//Local
private String strConn = #"Data Source=.\SQLEXPRESS;" +
#"AttachDbFilename='D:\JP Stuff\BELGIUM CAMPUS\3de Jaar\SOFTWARE ENGINEERING\ASSIGNMENT\Premier Service Solutions\Premier Service Solutions\DB\db_PSS_1.0.mdf';" +
#"Integrated Security=True;" +
#"User Instance=True";
private SqlConnection conn;
//Properties
public SqlConnection Conn
{
get { return this.conn = new SqlConnection(this.strConn); }
}
//Constructor
public sqlConn()
{
}
}
class sqlFactory : sqlConn
{
//Constructor
public sqlFactory()
: base()
{
}
//Insert Record into database
public void Create(String[] dbData, List<String> strRow)
{
using (SqlConnection sqlCon = this.Conn)
using (SqlCommand com = new SqlCommand("SELECT * FROM " + dbData[0], sqlCon))
{
SqlDataAdapter da = new SqlDataAdapter(com);
SqlCommandBuilder sqlbuilder = new SqlCommandBuilder(da);
DataSet ds = new DataSet();
da.Fill(ds, dbData[0]);
DataRow dr = ds.Tables[dbData[0]].NewRow();
for (int i = 0; i < dbData.Count() - 2; i++)
{
dr[i + 1] = strRow[i];
}
ds.Tables[dbData[0]].Rows.Add(dr);
da.Update(ds, dbData[0]);
}
}
}
class dbDefinitions : sqlFactory
{
public static Dictionary<String, String[]> columns;
static dbDefinitions()
{
columns = new Dictionary<String,String[]>();
//tblCall Definition
#region call
String[] data = new String[]
{
"tblCall", "call_ID_PK", "call_emp_ID_FK",
"call_Description", "call_Notes", "call_Start_Time",
"call_End_Time", "call_Job_FK"
};
columns.Add("call", data);
#endregion
}
}
This may not answer your question fully, but you can improve this code in several ways.
Composition versus Inheritance
First, understand and apply composition over inheritance. Composition is a "has a" relationship, whereas inheritance is a "is a" relationship.
For example, if a Person class has a property of the Phone class type, it's composition.
public class Person
{
public Phone Phone {get; set;}
}
If a Person class descends from the Phone class it's inheritance.
public class Person : Phone
{
}
In your code, sqlFactory should contain a sqlConn instead of inheriting from it.
Composition gives more flexibility, especially since C# doesn't allow for multiple inheritance. Read here for more: Prefer composition over inheritance?
SQL Injection
You should never build sql statements using string concatenation like this.
"SELECT * FROM " + dbData[0]
This creates a potential security hole that allows for SQL Injection attacks. You should always use parameterized queries to prevent against this.
Read Tip/Trick: Guard Against SQL Injection Attacks to understand SQL Injection attacks and how to prevent them.
Coding Convention
The nearly universally accepted convention for class naming amongst C# developers is to use PascalCase, where the first letter of every word in your class name is capitalized. Your classes would be SqlFactory, SqlConn, and DbDefinition.
This guide gives fairly commonly used conventions: C# Coding Standards document
Your DAO should have backing classes that act as models to the tables. These models should all have a common interface. Your DAO should then have instances of the Model interface with XML configuration pointing to the proper tables for the model. This will prevent you from having to define your tables in your code. Your data access layer is the layer that accesses your data, not the layer that defines your data. Your models should define the data.
Try defining the database schema information in an xml file and read it to create the CRUD operations.
I wanted to update my dataset changes to my database, so I used this sort of code:
SqlCommandBuilder mySqlCommandBuilder = new SqlCommandBuilder(sqladap);
sqladap.Update(ds, TableName);
While it works properly I have used this code for another dataset in my project but the second one does not work. I traced this code and saw the rows of the dataset. It contains both last fetched rows and new rows but the SQLDataAdapter updates any data and also it does not throw an error.
here is the full code:
public static SqlDataAdapter AdapterStoredProcedure(string sp_Name, object obj)
{
ClsEventLogs EventLogs = new ClsEventLogs();
try
{
SqlConnection connection = SQLDBConnection();
SqlDataAdapter sqladap = new SqlDataAdapter(sp_Name, connection);
sqladap.SelectCommand.CommandType = CommandType.StoredProcedure;
if (obj != null)
{
Type t = obj.GetType();
string str = string.Empty;
System.Reflection.FieldInfo[] fields = t.GetFields();
foreach (System.Reflection.FieldInfo field in fields)
{
sqladap.SelectCommand.Parameters.Add(new SqlParameter(field.Name, SqlDbType.VarChar, 200));
sqladap.SelectCommand.Parameters[field.Name].Value = field.GetValue(obj).ToString();
}
}
return sqladap;
}
catch(Exception er)
{
EventLogs.Eventlog("clsDataStore : ExecuteStoredProcedure", er.Message, ClsEventLogs.EventType.etCriticalError, false);
return null;
}
}
// Creating Adapter
SqlDataAdapter dAdap = null;
DataSet ds = new DataSet();
dAdap = clsDataStore.AdapterStoredProcedure("sp_SelectTbl_Client", null);
dAdap.Fill(ds, "tbl_client");
//here is where i'm Updating the dataset
SqlCommandBuilder mySqlCommandBuilder = new SqlCommandBuilder(sqladap);
sqladap.Update(ds, TableName);
You'll have to look (Debugger) at the generated SQL Update/Insert statements. Most likely they are flawed or even empty.
The CommandBuilder is extremely limited, it only deals with very simple SELECT a, b FROM table statements.
You will probably find that the SP that doesn't work contains a JOIN, computed column or something like that.
Best course: provide your own Update statements or SPs
To ask the dumb question: did you tell your adapter to commit the changes after calling the Update method?
EDIT: OK, now that you've posted your code, I have to ask another dumb question: what are you looking at to determine if the update worked? Are you connecting to a remote database right now, or a test database in the project? If it's the latter, then if you are rebuilding each time (something I'm in the habit of doing) then your working copy of the database (in the \bin directory) gets blown away and replaced with a fresh copy from wherever it's referenced from in the project. That assumes, of course, that you're using an embedded DB (like MSSQLCE).
One of the problems I am having with c# is that there seems to be so much information online that I am having trouble finding the right answer to the most basic of questions.
I am trying to do something simple:
I have a button, I click it, it queries the database and populates a datagrid on my windows form.
private void button1_Click(object sender, EventArgs e)
{
SqlConnection c = new SqlConnection("Data Source = (local); Integrated Security = true; Initial Catalog = pubs; ");
c.Open();
// 2
// Create new DataAdapter
SqlCommand cmd = c.CreateCommand();
cmd.CommandText = #" SELECT * FROM Authors ";
SqlDataReader reader = cmd.ExecuteReader();
dataGridView1.DataSource = reader;
dataGridView1.DataBind();
}
Error 1 'System.Windows.Forms.DataGridView' does not contain a definition for 'DataBind' and no extension method 'DataBind' accepting a first argument of type 'System.Windows.Forms.DataGridView' could be found.....
I am probably missing a "using directive" but which one? Multiple Google searches tell me how to bind a Yahoo RSS Feed to a gridview or provide various obscure details on "using directives".
Maybe I am using the SqlDataReader incorrectly. Should I be using SqlAdapter instead? What happened to all the good basic tutorials online for windows c# forms? A few months ago I found a couple great tutorials, but they seem to have lost their pageranking and I cannot find them anymore using basic google searches.
You're not missing a using directive; it's just that the WinForms DataGridView doesn't have a DataBind method. Just assigning DataSource is enough to get the binding to happen; you don't need to call a method as well.
However, I don't think you can assign a SqlDataReader as the DataSource. According to the DataSource property documentation in MSDN, the DataSource must be an IList, an IListSource, an IBindingList or an IBindingListView. You will probably instead need to load the data into a DataTable or DataSet (or an object data source populated using an object-relational mapper), and use that as the DataSource.
Try this instead:
using (SqlConnection conn = new SqlConnection("your connection string"))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(#"SELECT * FROM Authors", conn))
{
using (SqlDataAdapter adap = new SqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
adap.Fill(dt);
dataGridView1.DataSource = dt;
}
}
}
The DataGridView does not have a DataBind() method because it doesn't need one. Setting the DataSource property handles the binding for you. The using() blocks will automatically close and dispose of everything for you as well.
Note: you should replace "your connection string" with a valid connection string. I left yours out of my sample to avoid the horizontal scrollbars, and I'm not sure yours is valid anyway. You may get a runtime error when you run the code using your connection string. www.connectionstrings.com is a great resource for figuring out a valid connection string.
Update: instead of the nested using() blocks, you can also do it like this:
using (SqlConnection conn = new SqlConnection("..."))
using (SqlCommand cmd = new SqlCommand(#" SELECT * FROM Authors", conn))
using (SqlDataAdapter adap = new SqlDataAdapter(cmd))
{
conn.Open();
DataTable dt = new DataTable();
adap.Fill(dt);
dataGridView1.DataSource = dt;
}
I prefer the nested style, but it's "half of one, six dozen of the other" to me. Typically, I would encapsulate code like this into a class (called "DataGetter" or whatever) with a static method like:
public static DataTable GetData(string query)
{
// do all the connecting and adapting and filling and so forth
}
so that the code in your button click would be as simple as:
dataGridView1.DataSource = DataGetter.GetData("SELECT * FROM AUTHORS");
However, I would not do this in any performance-critical section of my code, since you sometimes want to keep a SqlCommand object (and its SqlParameter collection) around between calls. You do not need to keep SqlConnection objects around between calls, thanks to connection pooling (in fact, you don't want to keep them around under any circumstances).