Fill observableCollection directly from sql server - sql-server

I would like to know if there is any way to fill ObservableCollection directly from SQL server.
Currently I am loading my data into DataTable (using sqlDataAdapter) and do a conversion to ObservableCollection manually and it very inefficient.
How it can be done?

OK, I have found a way to do this:
It can be done using SqlDataReader.
public ObservableCollection<DataItem> LoadCategoriesData()
{
Command = new SqlCommand(StoredProcedure, Connection);
Command.CommandType = CommandType.StoredProcedure;
ObservableCollection<DataItem> myColl = new ObservableCollection<DataItem>();
Connection.Open();
SqlDataReader reader = Command.ExecuteReader();
while (reader.Read())
{
int mainCatID = reader.GetInt32(0);
string categoryName = reader.GetString(1);
//adding row data to observable
myColl.Add(new DataItem(mainCatID, categoryName));
}
Connection.Close();
return myColl;
}

Related

Store and retrieve data table into Varbinary column

For some reason I had to store a DataTable variable in a Varbinary column of a SQL Server table, but I get errors.
This is store code:
// Read DataTable to Byte array
DataTable dtgrd = new DataTable();
DataAccess ds = new DataAccess();
DataSet dst = new DataSet();
dst.Tables.Add(dtgrd);
string xmlString = dst.GetXml();
MemoryStream ms = new MemoryStream();
XmlDocument xml = new XmlDocument();
xml.LoadXml(xmlString);
xml.Save(ms);
byte[] xmlBytes = ms.ToArray();
// Store DataTable into database
SqlConnection CN = new SqlConnection(Global.cs);
string str = #"INSERT INTO...... ";
SqlCommand SqlCom = new SqlCommand(str, CN);
SqlCom.Parameters.Add(new SqlParameter("#FKDocInReqID", FKDocInReqID));
SqlCom.Parameters.Add(new SqlParameter("#value", (object)xmlBytes));
SqlCom.Parameters.Add(new SqlParameter("#Data", ReportTitle));
SqlCom.Parameters.Add(new SqlParameter("#DocUploadUser_secuserID", Global.S_UserID));
CN.Open();
decimal id =(decimal) SqlCom.ExecuteScalar();
CN.Close();
The store code has worked correctly and in the database, the columns has the proper bytes.
But the retrieve code does not work:
string s = #"select * from .... where id={0} ";
s = string.Format(s, id);
DataTable dt = new DataTable();
dt = ds.doSelect(s);
using (System.IO.MemoryStream memStream1 = new System.IO.MemoryStream((byte[])dt.Rows[0]["Value"]))
{
dataGridView1.DataSource = FromBytes(memStream1.ToArray());
dataGridView1.Refresh();
dataGridView1.Show();
}
and
static DataTable FromBytes(byte[] arr)
{
using (var ms = new MemoryStream(arr))
{
return (DataTable)new BinaryFormatter().Deserialize(ms);//**ERROR Raised Here**
}
}
static byte[] ToBytes(DataTable table)
{
using (var ms = new MemoryStream())
{
table.RemotingFormat = SerializationFormat.Binary;
new BinaryFormatter().Serialize(ms, table);
return ms.ToArray();
}
}
this error is raised:
error message
The example code on Microsoft's website uses XmlTextReader
static DataTable FromBytes(Stream st)
{
var ds = new DataSet();
using (XmlTextReader xmlReader = new XmlTextReader(st))
{
ds.ReadXml(xmlReader);
}
return ds.Tables[0];
}
I'll leave you to think about the obvious design flaws in storing one table within another.
this is how I figure out this problem maybe help to someone else.
instead of save data into Varbinary field save it to xml in nvarchar(max) and then retrieve it :
//Retrieve Process:
string s = #"select * from .... where id={0} ";
s = string.Format(s, ID);
DataTable dtlist = new DataTable();
DataAccess ds = new DataAccess();
dtlist = ds.doSelect(s);//doselect is function that run select sql command
XmlDocument xml = new XmlDocument();
xml.LoadXml(dtlist.Rows[0]["Data"].ToString());//data is column name that store xml in it
StringReader theReader = new StringReader(xml.InnerXml);
DataSet theDataSet = new DataSet();
theDataSet.ReadXml(theReader);
gridEX1.DataSource = theDataSet.Tables[0];

ds.Tables["TableName"] threw an exception "System.Data.DataTableCollection.this[string].get returned null."

I'm working on a Exporting DataGridView to CSV File and I have this problem:
When i try with table name ( ds.Tables["tableName"] ) it threw an exception "System.NullReferenceException: 'Object reference not set to an instance of an object.'
System.Data.DataTableCollection.this[string].get returned null.
"
but it is working with the index of table: ds.Tables[0].
In my case I have only the names of the table.
I've tried with ds.Tables["dbo.tableName"] also ds.Tables[(row.Cells["table_name"].Value.ToString())]
this is my code:
{
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
foreach (DataGridViewRow row in TableNamesGrid.Rows)
{
bool isSelected = Convert.ToBoolean(row.Cells["CheckBox"].Value);
if (isSelected)
{
StringBuilder stringBuilder = new StringBuilder();
SqlDataAdapter sqlData = new SqlDataAdapter("SELECT * FROM " + row.Cells[1].Value, sqlConnection);
DataSet ds = new DataSet();
sqlData.Fill(ds);
foreach (DataRow dataRow in ds.Tables[(row.Cells["table_name"].Value.ToString())].Rows)
{
for (int i = 0; i <= ds.Tables[(row.Cells["table_name"].Value.ToString())].Rows.Count; i++)
{
stringBuilder.Append(dataRow[i].ToString() + ",");
}
stringBuilder.Append("\r\n");
}
StreamWriter file = new StreamWriter(#"D:\Projects\AlatiWF\data.csv");
file.WriteLine(stringBuilder.ToString());
file.Close();
}
}
}
}
The SqlDataAdapter is not smart enough to work out that your query is just accessing a single table, so it will always return tables named like this: "Table0", "Table1", "Table2", etc.
Table[0] works because it's accessing the table called "Table0". You can give the tables sensible names after your call to sqlData.Fill(ds) by doing something like:
ds.Tables[0].TableName = "SensibleTableName";
Directly fill the Datatable and without Dataset.
DataTable dt = new DataTable();
sqlData.Fill(dt);
foreach (DataRow dataRow in dt.Rows)
{

Linq To Sql Conversation In Wcf Service

Can you please provide an answer following sql query to linq . I have some knowledge about linq but i am confused about sql reader object ..
public AccountBalanceRequest AccountBalanceCheek(AccountBalanceRequest accountNumber)
{
using (SqlConnection conn = new SqlConnection(ConnectionString))
{
conn.Open();
var cmd = new SqlCommand("SELECT Account_Type,Account_Fees,Account_Balance,Over_Draft_Limit FROM Current_Account_Details WHERE Account_Number = '" + accountNumber.Account_Number + "'", conn);
cmd.CommandType = CommandType.Text;
var reader = cmd.ExecuteReader();
//read the result of the execute command.
while (reader.Read())
{
//assuming that your property is the same as your table schema. refer to your table schema Current_Account_Details
accountNumber.Account_Type = reader["Account_Type"].ToString();
accountNumber.Account_Fee = reader["Account_Fees"].ToString();
accountNumber.Account_Balance = reader["Account_Balance"].ToString();
accountNumber.Over_Draft_Limit = reader["Over_Draft_Limit"].ToString();
}
return accountNumber;
}
}
First you have to have DbContext which you must instantiate in using(usual practice):
using (DbContext db = new DbContext())
{
var results = (from ad in db.Current_Account_Details
where ad.Account_Number == accountNumber.Account_Number
select ad).ToList();
}
Make sure you have created the object data model from database.
I do not get the other part of your post but this would be the general idea of how to write Linq2Entities queries.

How can we use both sql and oracle database connection using one object only

I wants to fetch the data from database using C++.Net. I need to do this irrespective of db used in the system. But i don't want to change my code for each database. I am looking for a solution in C++.Net, please do help..
This is what i have now;
Oracle:
OracleConnection *myOracleConnection;
OracleDataAdapter * myDataAdapter;
DataSet * myDataSet;
myOracleConnection = new OracleConnection(S"Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.2.175)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=SCDB)));User Id=user;Password=pw;");
myOracleConnection->Open();
myDataAdapter = new OracleDataAdapter(S"select dbms_xmlgen.getxml(' select * from SampleTable') from dual ",myOracleConnection);
myDataSet = new DataSet("Sample");
Sql:
`SqlConnection *mySQLConnection;
SqlDataAdapter * myDataAdapter;
DataSet * myDataSet;
mySQLConnection = new SqlConnection(S"Data Source=(local);Initial Catalog=myDb;User Id=user;Password=pw;");
mySQLConnection->Open();
myDataAdapter = new SqlDataAdapter(S"select * from [SampleTable]",mySQLConnection);
myDataSet = new DataSet("Sample");`
i wants to do both connection using one connection object. Is there any idea to achieve this???
I can't give you c++ code, but I can help you how to do it. It will be difficult to do it in one connection, but your can get a DataSet back which will work, and you only have to do the code once.
Create a method will return a DataSet, and pass the query as well as what type of connection should be used, in this method depending on tour connection type you do your query and return your result.
You can also add a connectionstring if you wish.
Something like this (it is c# though)
DataSet GetDataSet(string sqlQuery, ConnectionType connType)
{
DataSet dataset = new DataSet("aDataSet");
using (DataTable table = dataset.Tables.Add("aDataTable"))
{
switch (connType)
{
case ConnectionType.MSSQL:
using (var conn = new SqlConnection("Data Source=(local);Initial Catalog=myDb;User Id=user;Password=pw"))
{
using (var cmd = new SqlCommand(sqlQuery, conn))
{
conn.Open();
using (var reader = cmd.ExecuteReader())
{
table.Load(reader);
}
}
}
break;
case ConnectionType.Oracle:
using (var conn = new OracleConnection("Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.2.175)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=SCDB)));User Id=user;Password=pw"))
{
using (var cmd = new OracleCommand(sqlQuery, conn))
{
conn.Open();
using (var reader = cmd.ExecuteReader())
{
table.Load(reader);
}
}
}
break;
default:
break;
}
}
return dataset;
}
enum ConnectionType { MSSQL, Oracle }

Change DataBase using DataGrid

I want to output data from DataBase to DataGrid, using ADO.NET.
Can you tell me how to do that?
When I'm writing something in dataGrid it's changing in database. I use WPF, .NET 4.0.
Code:
class ThemeEditor
{
private SqlDataAdapter da;
private DataSet ds;
private SqlConnection cn;
public ThemeEditor(DataGrid dg)
{
SqlCommand cmd;
string source = "server=(local); integrated security=SSPI; database=tests";
string reqest = "SELECT Theme,Stuff FROM Themes";
cn = new SqlConnection(source);
da = new SqlDataAdapter();
ds = new DataSet();
cmd = new SqlCommand(reqest, cn);
da.SelectCommand = cmd;
da.Fill(ds, "Theme");
dg.ItemsSource = ds.Tables["Theme"].DefaultView;
}
}
maybe it'll be helpfull!
http://support.microsoft.com/kb/307587
or this... http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/3adacd01-f08f-4059-bbce-bff736a5188e

Resources