Filling Datatable through linq - c#

I'm new to linq and trying to understand it. I'm trying to fill a data table through linq but getting an error in the sql command adapter.
Below is the code which I'm using, don't know if I'm using it the right way!
This is the error I'm getting:
Error 7 Cannot implicitly convert type
'System.Linq.IQueryable' to
MySql.Data.MySqlClient.MySqlCommand'
{
northwindEntities1 nw = new northwindEntities1();
var query = from c in nw.customers
join o in nw.orders on c.CustomerID equals o.CustomerID // first join
join od in nw.orderdetails on o.OrderID equals od.OrderID // second join
join p in nw.products on od.ProductID equals p.ProductID // third join
where c.ContactName.StartsWith("Maria Anders")
select new {
o.CustomerID,
c.ContactName,
o.OrderID,
p.ProductID,
p.ProductName,
od.Quantity,
p.UnitPrice
};
MySqlDataAdapter da = new MySqlDataAdapter();
da.SelectCommand = query;
DataTable datatable = new DataTable();
da.Fill(datatable); // getting value according to imageID and fill dataset
ReportDocument crystalReport = new ReportDocument(); // creating object of crystal report
crystalReport.Load(Server.MapPath("~/custreport.rpt")); // path of report
crystalReport.SetDataSource(datatable); // binding datatable
CrystalReportViewer1.ReportSource = crystalReport;
crystalReport.ExportToHttpResponse
(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, Response, true, "PersonDetails");
}

A SQL query is not the same as a LINQ query, they are totally different.
LINQ by itself is a set of query language features that used are to query different data sources, but it is not the same as a SQL query. You have miss understand that. So you can't pass it to act like SQL query.
You can't pass System.Linq.IQueryable which coming from the variable linq to the MysqLCommand CommandText Property, you should pass a string which should be the MysQL query not LinQ query. Something like this:
string query = "Select * FROM Customers INNER JOIN ..."; //you have to pass sql query
MySqlDataAdapter da = new MySqlDataAdapter();
da.SelectCommand = query;
...

Related

Record count in c# query result

How can i get Total records count in query result
SqlConnection con1 = new SqlConnection(ConfigurationManager.ConnectionStrings["con1"].ConnectionString);
string sql = "select Fare , OrderAmount FROM orderitems OI INNER JOIN Orders O ON O.OrderID = OI.OrderID WHERE PaymentStatusID = 1 AND o.orderid ="+Orderid;
SqlCommand comd = new SqlCommand(sql, con1);
con1.Open();
comd.ExecuteNonQuery();
Above is my sql query i need result count, can some one help me
Thanks in advance.
ExecuteNonQuery is used for query like insert/update/delete.
Use ExecuteScalar instead:
string sql = "select count(*) FROM orderitems OI INNER JOIN Orders O ON O.OrderID = OI.OrderID WHERE PaymentStatusID = 1 AND o.orderid ="+Orderid;
SqlCommand comd = new SqlCommand(sql, con1);
con1.Open();
int count = Convert.ToInt32(comd.ExecuteScalar());
If you don't need the Fare and the OrderAmount (a bit strange, since the sql script you have written contains them), you could replace them with a COUNT(*).
string sql = "select COUNT(*) FROM orderitems OI INNER JOIN Orders O ON O.OrderID = OI.OrderID WHERE PaymentStatusID = 1 AND o.orderid ="+Orderid;
Then you can read this fairly easily, like below:
int numberOfRecords = Convert.ToInt32(comd.ExecuteScalar());
On the other hand, if you need them, you could count the number of records in the sql reader you will use to read those results, like below:
SqlDataReader sqlReader = comd.ExecuteReader();
int numberOfRecords = 0;
while(sqlReader.Read())
{
// do things
numberOfRecords++;
}
Note
In any case, you can't use the ExecuteNonQuery method, since you want to read something from a database. You don't want to create, update or delete something. Only in the latter cases we use this method.
One more important note is about the security of the queries you build and then execute is to avoid string concatenation for passing the values of parameters. This makes your app vulnerable to sql injections, one of the major ways of attacks. Instead of doing this, you could use a sql parametrized query, like below:
string sql = "select Fare , OrderAmount FROM orderitems OI INNER JOIN Orders O ON O.OrderID = OI.OrderID WHERE PaymentStatusID = 1 AND o.orderid=#Orderid";
SqlCommand cmd = new SqlCommand(sql, con1);
cmd.Parameters.Add("#Orderid",OrderId);

Valid SQL Statement Returning 'Syntax Error" in Asp.NET

I'm making an ASP.Net web application, but it is returning a syntax error whenever I try to load the page.
My DB schema can be seen here http://sqlfiddle.com/#!2/739c4/7
Here is the SQL query:
SELECT
tblOrderTransactions.ordertransaction_orderid AS orderid,
tblProducts.product_name AS productname,
tblOrders.order_customer AS ordercustomer
FROM
tblProducts
LEFT JOIN tblOrderTransactions
ON tblProducts.product_id = tblOrderTransactions.ordertransaction_productid
LEFT JOIN tblOrders
ON tblOrderTransactions.ordertransaction_orderid = tblOrders.order_id
WHERE
(
(
(
tblOrderTransactions.ordertransaction_orderid
)
=3
)
) and (
(
(tblOrders.order_customer)
=3
)
)
The SQL works in sqlfiddle, and if I remove the part that says
LEFT JOIN tblOrders
ON tblOrderTransactions.ordertransaction_orderid = tblOrders.order_id
in my web application, the table loads. Adding this second INNER JOIN seems to be messing it up, but the same query works in sqlfiddle, so I believe the SQL is correct.
The error message I receive is
Syntax error (missing operator) in query expression 'tblProducts.product_id = tblOrderTransactions.ordertransaction_productid LEFT JOIN tblOrders ON tblOrderTransactions.ordertransaction_orderid = tblOrders.order_i'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Data.OleDb.OleDbException: Syntax error (missing operator) in query expression 'tblProducts.product_id = tblOrderTransactions.ordertransaction_productid LEFT JOIN tblOrders ON tblOrderTransactions.ordertransaction_orderid = tblOrders.order_i'.
C# Code inside the application:
string orderID = Request.QueryString["id"];
OleDbConnection conn = new OleDbConnection();
conn.ConnectionString = ConfigurationManager.ConnectionStrings["finalConnString"].ConnectionString;
string commText = #"SELECT tblOrderTransactions.ordertransaction_orderid AS orderid, tblProducts.product_name AS productname
FROM tblProducts
LEFT JOIN tblOrderTransactions
ON tblProducts.product_id = tblOrderTransactions.ordertransaction_productid
LEFT JOIN tblOrders
ON tblOrderTransactions.ordertransaction_orderid = tblOrders.order_id
WHERE (((tblOrderTransactions.ordertransaction_orderid)=?)) ";
conn.Open();
OleDbCommand comm = conn.CreateCommand();
comm.Connection = conn;
comm.CommandText = commText;
OleDbParameter param;
param = comm.CreateParameter();
param.DbType = DbType.Int32;
param.Direction = ParameterDirection.Input;
param.Value = Int32.Parse(orderID);
comm.Parameters.Add(param);
//param = comm.CreateParameter();
//param.DbType = DbType.Int32;
//param.Direction = ParameterDirection.Input;
//param.Value = Session["LoggedInId"];
//comm.Parameters.Add(param);
OleDbDataReader reader = comm.ExecuteReader();
if (reader.HasRows)
{
rptOrders.DataSource = reader;
rptOrders.DataBind();
lblOrderNumber.Text = orderID.ToString();
}
else
{
Response.Write("You are not authorized to view this order.");
}
//Free up the connection
conn.Close();
The SQL Statement must have the joins nested in parentheses because of Access specific syntax (Thank you #MattiVirkkunen for that knowledge).
The correct way to write this SQL statement is:
SELECT tblOrderTransactions.ordertransaction_orderid, tblProducts.product_name, tblOrders.order_customer
FROM tblProducts
INNER JOIN (tblOrders
INNER JOIN tblOrderTransactions
ON tblOrders.[order_id] = tblOrderTransactions.[ordertransaction_orderid])
ON tblProducts.[product_id] = tblOrderTransactions.[ordertransaction_productid]
WHERE (((tblOrderTransactions.ordertransaction_orderid)=3)) and (((tblOrders.order_customer)=3))
First, I would suggest working with aliases to keep your query a little shorter to read (and type) such as below.
SELECT
OT.ordertransaction_orderid AS orderid,
P.product_name AS productname,
O.order_customer AS ordercustomer
FROM
tblProducts P
LEFT JOIN tblOrderTransactions OT
ON P.product_id = OT.ordertransaction_productid
LEFT JOIN tblOrders
ON OT.ordertransaction_orderid = O.order_id
WHERE
OT.ordertransaction_orderid = 3
and O.order_customer = 3
Second, it does look completely legit and nothing glaring out as invalid. But error of loading the page MIGHT be due to no records being returned. You have your query with left-joins, but then throwing in your WHERE clause for both the "tblOrderTransactions" and "tblOrders" tables changes it to an INNER JOIN result.
So, your query looking for order ID = 3 and also the customer = 3, what if that was not the case, that order #3 was customer #1 which would result in NO RECORDS.
Getting back to now seeing your posted syntax, it looks unbalanced parens ((( )) that might be the issue.
And a final review.. Your "ID" from the query string. Is it properly doing an int.Parse() against it? I know on some instances of int.parse() I've done in the past, if the string started with a space vs actual number, int.Parse() would throw an error... Confirm the incoming values and did it really convert as you expected.

SQL SELECT COMMAND WITH JOIN in C#

CourseRepeater cr = new CourseRepeater();
List<CourseRepeater> course = new List<CourseRepeater>();
string sql = "SELECT u.Name, u.Surname, c.Name, c.ClosingDate, c.BeginDate FROM Course AS c, JOIN Users AS u on u.UserID=c.UserID";
DataTable dt = DataBase.SQLSelect(sql);
if (dt.Rows.Count != 0)
{
cr.Name = dt.Rows[0]["Name"].ToString(); // ?
}
I have Database class that contains SQLSelect().Here there is not problem.
My question is so : If I want to get Users.Name, dt.Rows[0]["Name"] in this row ,I should write dt.Rows[0]["Name"] or dt.Rows[0]["u.Name"] ?
Might as well move the comment to the answer.
You should alias the fields in the query.
The other option are more fragile or not as clear.
SELECT u.Name UsersName, c.Name CourseName FROM...

Comparing two datatables through Linq

Hi I'm trying to compare two datatable through Linq. But I get this exception:
Specific cast is invalid
Please help me as I am new to Linq. This is the code I'm using:
var matched1 = from table1 in dtAvailableStores.AsEnumerable()
join table2 in dtControlStores.AsEnumerable()
on table1.Field<int>("STORE_NBR")
equals table2.Field<int>("STORE_NBR")
select table1;
Here STORE_NBR is a string value.
You can have a fairly good idea with this piece of code:
var qry1 = datatable1.AsEnumerable().Select(a => new { MobileNo = a["ID"].ToString() });
var qry2 = datatable2.AsEnumerable().Select(b => new { MobileNo = b["ID"].ToString() });
var exceptAB = qry1.Except(qry2);
DataTable dtMisMatch = (from a in datatable1.AsEnumerable() join ab in exceptAB on a["ID"].ToString() equals ab.MobileNo select a).CopyToDataTable();
References:
Compare two datatable using LINQ Query
Compare two DataTables for differences in C#?
This would happen if that field isn't actually an int.

MySql query: get all customers that has their ID in both Customer and Customer_x_Billing table

I am using a C# console app to get some data from a MySql database and I have some problems getting a query right
As it is now:
SELECT * FROM Customer
WHERE EXISTS ( SELECT * FROM Customer_x_Billing c WHERE Customer.`customer id` = c.customer_id)
AND 2011 -04 -03 < ( SELECT last_changed FROM Customer_x_Billing c WHERE Customer.`customer id` = c.customer_id )
ORDER BY Customer.`customer id`
How can I improve this one?
I want to get all customers that has their ID in both Customer and Customer_x_Billing table and where the last_changed date in Customer_x_Billing is greater than a parameter (2011-04-03 in this case). If I set the date to 2012-04-03 it shouldn't return any row but it returns all records that match the first condition (exist in both).
Try below one
SELECT * FROM Customer
INNER JOIN
Customer_x_Billing ON Customer.`customer id` = Customer.customer_id
WHERE last_changed > 2011 -04 -03
ORDER BY Customer.`customer id`
problem with you query is you are scanning Customer_x_Billing table two time which is not needed, its better to go for one inner join which will stisfy you first condition the exists one and second satisfy by writing the where clause.
SELECT c.* FROM Customer c INNER JOIN Customer_x_Billing cb ON cb.customer_id = c.id WHERE DATE(cb.last_changed) > '2011-04-03' ORDER BY c.id;
If I read your question right I belive you can achieve this with an INNER JOIN...
SELECT *
FROM Customer c
INNER JOIN Customer_x_Billing b
ON c.customer_id = b.customer_id
WHERE last_changed_date > '2011-04-03'
SELECT Customer.* FROM Customer c INNER JOIN Customer_x_Billing b
ON c.`customer id`=b.`customer id`
WHERE last_changed>'2011-04-03'
ORDER BY c.`customer id`
Anyway beware of dates in your query...
More or less like this.
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = con;
cmd.CommandText
= "SELECT * FROM Custromer c JOIN Customer_x_Billing cb ON c.'customer id' = cd.'customer id' Where last_change < #lastChangeDate";
cmd.Parameters.AddWithValue("#lastChangeDate", new DateTime(2011,04,03));
using (SqlDataReader drd = cmd.ExecuteReader())
{
while (drd.Read())
{
// Read from data reader
}
}
}
}
For sake of your application you should get familiar with some database tutorial, and try to understand the concept of relational databases.

Categories