Cross database query in C# to get Databases names list - c#

I'm using Entity Framework 6 (EF6) with C#. I'm trying to write a DB agnostic query to get all the databases names list.
For example:
with SQL Server exists something like
select * from master.sys.databases
WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb');
with MySQL
SHOW DATABASES
and so on with Postgres, Oracle, etc.
So the question is if EF6 offers a way to get this list independently by the specific database.

You can do this :
public bool TestConnection(string connString, List<string> databases) {
using (context = new DatabaseContext(connString)) {
if (!context.Database.Exists())
return false;
string query = "select * from master.sys.databases WHERE name NOT IN('master', 'tempdb', 'model', 'msdb')";
var connection = context.Database.Connection;
DataTable dt_databases = new DataTable();
SqlDataAdapter dataAdapter = new SqlDataAdapter(query, connection.ConnectionString);
dataAdapter.Fill(dt_databases);
// Getting name from each dataRow
foreach (DataRow dr in dt_databases.Rows)
databases.Add(dr.ItemArray[0].ToString());
return true;
}
}
if you just want the name of databases, you can build your query like this:
string query = "select name from master.sys.databases WHERE name NOT IN('master', 'tempdb', 'model', 'msdb')";

Related

How to get a list of database names from a SQL Server instance using Entity Framework?

I would like to use Entity Framework (EF) to query a SQL Server instance and return a list of database names on that instance.
I can do this using the following code, but wondered if there was a way with EF?
public static string[] GetDatabaseNames(SqlConnection masterConn)
{
List<string> databases = new List<string>();
// retrieve the name of all the databases from the sysdatabases table
using (SqlCommand cmd = new SqlCommand("SELECT [name] FROM sysdatabases", masterConn))
{
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
databases.Add((string)rdr["name"]);
}
}
}
return databases.ToArray();
}
I should mention that I am new to EF and its capabilities / limitations.
You could simply send a raw query to your SQL Server through Entity Framework :
using (var context = new MyContext())
{
var dbNames = context.Database.SqlQuery<string>(
"SELECT name FROM sys.databases").ToList();
}
Sources : https://msdn.microsoft.com/en-us/library/jj592907(v=vs.113).aspx and https://stackoverflow.com/a/147662/2699126
You create view in SQL database
CREATE VIEW [dbo].[SysDatabasesView] AS SELECT * FROM sys.databases
then add this object into edmx

Populating Datagrid with Data from Multiple Tables

I need to populate a datagrid with the following columns.
invnumber,itemname,rate,quantity..
itemname,rate,quantity comes from 1 table while invnumber comes from another table
I used to do like this
string commandText = "SELECT invnumber,cname,date FROM inv_table WHERE invnumber LIKE #id";
SqlCommand command = new SqlCommand(commandText, conn);
string searchParam = String.Format("%{0}%", text_inv.Text);
command.Parameters.AddWithValue("#id", searchParam);
using (SqlDataAdapter sda = new SqlDataAdapter(command))
{
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
dataGridView2.DataSource = dt;
}
}
Now i cannot directly assign the data source as 2 different tables are involved
dataGridView2.DataSource = dt;
How can i get around this.
To emit combined result from 2 or more different tables in a table, use either INNER JOIN, LEFT JOIN, RIGHT JOIN or UNION statement depending on your need.
In this case, you need to join first table and other table to get desired results, assume invnumber is unique or primary key. Here is an example:
string commandText = "SELECT other.invnumber, inv.cname, inv.date FROM inv_table AS inv
INNER JOIN other_table AS other
ON inv.invnumber = other.invnumber
WHERE other.invnumber LIKE #id";
Or if you have already defined classes for each table, use LINQ to SQL with lambda expression:
DataContext dc = new DataContext();
var results = dc.InvTable.Join(OtherTable, inv => inv.invnumber, other => other.invnumber, (inv, other) => new { invnumber = other.invnumber, cname = inv.cname, date = inv.date });
Any improvements and suggestions welcome.
Create a new class for the data structure of the 2 different table, populate the new one and use. (easier and the most clear solution)

How to Compare Rows Stored in a Datatable with Multiple Tables' Rows in a Local SQL DB?

I have acquired data from my Oracle server and stored it in a DataTable (u). I have verified that the correct data has been acquired and stored.
I also have a local SQL database that has multiple tables, each with a column that carries a unique identifier.
What I would like to be able to do is compare the Oracle data stored in DataTable (u) with these various local SQL database tables, and then show the values(s) within the local SQL database tables that are identical to the values within the Oracle DataTable (u).
How would I perform this comparison while being able to tell what the matches are?
My current unfinished code:
using (OracleDataAdapter b = new OracleDataAdapter(sql2, conn))
{
conn.Open();
OracleCommand cmd2 = new OracleCommand(sql2, conn) { CommandType = CommandType.Text };
cmd2.BindByName = true;
cmd2.Parameters.Add(":user_name", OracleDbType.Varchar2).Value = cboUserName.SelectedValue;
var u = new DataTable();
b.Fill(u);
lstFunctions.DisplayMember = "Function_Name";
lstFunctions.ValueMember = "Function_Name";
lstFunctions.DataSource = u;
SqlConnection sodconnstring = new SqlConnection(#"***\SODGROUPS.sdf");
sodconnstring.Open();
SqlCommand sodcommand = new SqlCommand("SELECT * FROM tbl1, tbl2", sodconnstring);
SqlDataAdapter sodAdapter = new SqlDataAdapter(sodcommand);
var sodGroupData = new DataTable();
sodAdapter.Fill(sodGroupData);
conn.Close();
sodconnstring.Close();
}
Please let me know if you require any additional input.
Thanks.
Unless you share the schema of the tables (both oracle and SQL), it would be hard to guess a solution.
This line would return the join of tbl1 and tbl2 and I'm sure to compare the values, you would n't need a join .
SqlCommand sodcommand = new SqlCommand("SELECT * FROM tbl1, tbl2", sodconnstring)

Getting a selection of rows into C# from SQL CE

I am relatively new to C# and am developing an application that communicates with a local database (SQL Compact 3.5). I am fine with running standard select statements - but when it comes to getting that data into C# - I get a bit lost.
What I have so far is a 'delete' query that deletes all rows named 'Master'.
Now I have worked out that I actually need to get the IDs of those rows before I delete them (for database integrity purposes). I have no problems running a standard select query - my problem is getting a selection of rows from SQL CE into a C# application (using arrays or datatables or whatever is most logical/convenient).
This is what I have at the moment, but it only returns one value, not a selection:
string sql = "select listid from list where ShortDesc='Master'";
SqlCeCommand cmdGetOldMasterId = new SqlCeCommand(sql, DbConnection.ceConnection);
int oldKey = (int)cmdGetOldMasterId.ExecuteScalar();
Console.WriteLine("Old ID: " + oldKey);
I need to be able to do perform a foreach{ } loop on each of the returned rows. Any ideas how I can do this in C#?
You need to use a SqlCeDataReader instead of a ExecuteScalar if you suppose that your sql statement returns more thant one row of data
string sql = "select listid from list where ShortDesc='Master'";
SqlCeCommand cmdGetOldMasterId = new SqlCeCommand(sql, DbConnection.ceConnection);
SqlCeDataReader reader = cmdGetOldMasterId.ExecuteReader();
while(reader.Read())
{
Console.WriteLine(reader[0].ToString());
// or, if your listid is an integer
// int listID = reader.GetInt32(0);
}
another possibility is to use a SqlCeDataAdapter to fill a DataTable (this is less performant, but more useful if you need to process your data later in a different method)
string sql = "select listid from list where ShortDesc='Master'";
SqlCeCommand cmdGetOldMasterId = new SqlCeCommand(sql, DbConnection.ceConnection);
SqlCeDataAdapter da = new SqlCeDataAdapter(cmdGetOldMasterId);
DataTable dt = new DataTable();
da.Fill(dt);
....
foreach(DataRow r in dt.Rows)
{
Console.WriteLine(r["listid"].ToString());
}
SqlCeCommand has several execution methods
ExecuteNonQuery - to execute sql that does not need to return something
ExecuteScalar - for SELECT queries returning one value (don't mix with one row)
ExecuteReader - for SELECT queries returning >=0 rows
http://msdn.microsoft.com/en-us/library/182ax5k8.aspx
var reader = cmdGetOldMasterId.ExecuteReader();
while(reader.Read())
{
// reader[0], reader[1]...
}

How can I get a list of tables in an Access (Jet) database?

I need to see if a table exists in an Access database used by my c# program. Is know there are SQL commands for other databases that will return a list of tables. Is there such a command for Access/Jet databases?
Try the GetSchema()
connection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\\access.mdb";
connection.Open();
DataTable userTables = connection.GetSchema("Tables");
Full code : Get List of Tables in an Access Database - ADO.NET Tutorials
// Microsoft Access provider factory
DbProviderFactory factory =
DbProviderFactories.GetFactory("System.Data.OleDb");
DataTable userTables = null;
using (DbConnection connection =
factory.CreateConnection())
{
// c:\test\test.mdb
connection.ConnectionString = "Provider=Microsoft
.Jet.OLEDB.4.0;Data Source=c:\\test\\test.mdb";
// We only want user tables, not system tables
string[] restrictions = new string[4];
restrictions[3] = "Table";
connection.Open();
// Get list of user tables
userTables =
connection.GetSchema("Tables", restrictions);
}
// Add list of table names to listBox
for (int i=0; i < userTables.Rows.Count; i++)
listBox1.Items.Add(userTables.Rows[i][2].ToString())
here is answer for you : http://social.msdn.microsoft.com/Forums/en/adodotnetdataproviders/thread/d2eaf851-fc06-49a1-b7bd-bca76669783e
Something like this should do the trick. The clause Type = 1 specifies tables. Note that this will also include the system tables in the result set (they start with the prefix "MSys".
SELECT Name FROM MSysObjects WHERE Type = 1
that one worked for me
using (OleDbConnection con = new OleDbConnection(connectionString))
{
con.Open();
DataTable dt = con.GetSchema("Tables");
var selectNames = dt.Rows.Cast<DataRow>().Where(c => !c["TABLE_NAME"].ToString().Contains("MSys")).ToArray();
foreach (var item in selectNames)
{
// add names to comboBox
comboBox1.Items.Add(item["TABLE_NAME"]);
}
}

Categories