I use bind variables to get data from the SQL tables.
The code:
string commandText = string.Format("SELECT {0} FROM {1} WHERE {2} ORDER BY {3}", fields, from, whereStr, orderBy);
DbCommand command = GetSqlCommandWrapper(commandText);
int index = 0;
foreach (var item in whereParams)
{
command.Parameters.Add(new OracleParameter(item, whereParamsBy[index++]));
}
DataTable db = new DataTable();
DataSet dataSet = null;
dataSet = CurrentDatabase.ExecuteDataSet(command);
The CommandText:
fields = "TableA.*";
from = "TableA INNER JOIN TableB ON TableA .id = TableB.id";
whereStr = "TableA .id > 10";
orderBy = "TableA .id, TableB .id";
Everything works fine until I have to get data from 2 tables like the query:
select * from a inner join b on a.id = b.id where....
Someone can tell me how to do it?
Thanks in advance
The overall approach is not very nice, but in terms of getting what you want, this should do it.
fields = "*";
from = "TableA AS a INNER JOIN TableB AS B ON a.id = b.id";
whereStr = "a.id > 10";
orderBy = "a.id, b.id";
Set your input parameters to that, or just paste it in before the code you gave us and it will produce the command SELECT * FROM TableA AS a INNER JOIN TableB AS B ON a.id = b.id WHERE a.id > 10 ORDER BY a.id, b.id
Please note that orderBy = "a.id; DROP TABLE TableA;"; is a scary prospect
Related
Good day, everyone!
I'm working on a c# test automation script, and I have a sql query that returns a few values based on a few checks with cast, Case When, and Sum - but now we need to transfer it to Entity Framework as a linq query, and I'm not sure how to do so.
Could someone please assist me with this?
Here is my sql query
SELECT
co.orderId AS OrderId
,(SELECT
COUNT(*)
FROM ci_orders (NOLOCK) co
INNER JOIN Customer (NOLOCK) cust
ON cust.IdCustomer = co.customerId
WHERE cust.Email = c.Email
AND co.PaymentTransactionStatusID = 1)
AS CustomerOrdersCount
,co.PitStopStatus AS PitStopStatus
,(SELECT
SUM(ops.Price + ops.QuantityDiscount)
FROM OrderProductSelect (NOLOCK) ops
WHERE ops.OrderId = 2257327)
AS NetPrice
,CAST(CASE WHEN Exists (SELECT
oi.Id
FROM OrderIssues (NOLOCK) oi
LEFT JOIN PitStops ps
ON ps.Id = oi.PitStopId
WHERE oi.OrderId = co.orderId
AND IssueType = 'HighValueOrder') THEN 1
ELSE 0 END AS BIT)
AS IsHighValuePitStop
FROM ci_orders (NOLOCK) co
INNER JOIN Customer (NOLOCK) c
ON c.IdCustomer = co.customerId
WHERE co.orderId =2257327
#eldar - I tried below way
using (var context = GetDbContext())
{
var yellowOrder = context.YellowOrders.FirstOrDefault(x => x.OrderId == orderId);
var result = (from co in context.Orders
join c in context.Customers
on co.customerId equals c.IdCustomer
where co.orderId == orderId
select new
{
OrderId = orderId,
IsHighValuePitStop = (from oi in context.OrderIssues
join ps in context.PitStops
on oi.PitStopId equals ps.Id
where oi.OrderId == orderId && ps.IssueType == "HighValueOrder")
}).Any();
return yellowOrder != null;
}
You can achieve Case When in linq with a ternary (?:) operator. And since your queries are mostly inner selects your linq should look like this :
var result = await (
from co in context.ci_orders
join c in context.Customers on co.customerId eqals c.IdCustomer
where co.orderId =2257327
select new { // here your inner selects go
OrderId = co.orderId,
IsHighValuePitStop = (from oi in context.OrderIssues
join ps in context.PitStops on oi.PitStopId equals ps.Id
where oi.OrderId = co.orderId and oi.IssueType = 'HighValueOrder').Any(), // you could use ternary operator but Any already returns a boolean value ? true : false would be meaningless
NetPrice = context.OrderProductSelect.Where(r=> r.OrderId = 2257327).Sum(ops=> ops.Price + ops.QuantityDiscount),
co.PitStopStatus,
CustomerOrdersCount = (from co in context.ci_orders
join cust context.Customer on co.customerId equals cust.IdCustomer
where cust.Email = c.Email
&& co.PaymentTransactionStatusID = 1
select co).Count()
}).ToArrayAsync()
I am having diffculties joining a table in my code. Below you can see my code, I am getting an error on the join 2 table trying to connect my parts table.
if (query.Any()) // Check if REG is in the Database
{
int carID = query.FirstOrDefault().Id;
string carRegg = query.FirstOrDefault().regNo;
string carMake = query.FirstOrDefault().Make;
string carModel = query.FirstOrDefault().Model;
var test = (from a in dbC.Cars
where a.Id == carID
join b in dbC.Services on a.Id equals b.ServiceWrkNo
join c in dbC.PartsUseds on b.ServiceWrkNo equals c.PartsUsedNo
join d in dbC.Parts on c.PartsUsedNo equals d.PartName
select new
{
serviceNum = b.ServiceWrkNo,
PartNo = c.PartsUsedNo,
replacedParts = d.PartName
}).ToList();
the database I created from a model first method is below.
Your join do seems a little bit off -- could you try the join with the following columns
var test = (from a in dbC.Cars
where a.Id == carID
join b in dbC.Services on a.Id equals b.CarId
join c in dbC.PartsUseds on b.ServiceWrkNo equals c.ServiceServiceWrkNo
join d in dbC.Parts on c.PartsPartNo equals d.PartNo
select new
{
serviceNum = b.ServiceWrkNo,
PartNo = c.PartsUsedNo,
replacedParts = d.PartName
}).ToList();
I have a TBLCATEGORIES and a TBLPRODUCTS table. I want to get the category and sub-category name on the Products.aspx page with using joins:
The code below isn't working correctly:
DataTable dtProducts = system.GetDataTable(#"Select b.CategoryName,
a.* from TBLPRODUCTS a LEFT JOIN TBLCATEGORIES b ON
(A.SubCategoryID=B.CategoryID) order by a.ProductID desc");
if (dtProducts.Rows.Count > 0)
{
CollectionPager1.DataSource = dtProducts.DefaultView;
CollectionPager1.BindToControl = rpProducts;
rpProducts.DataSource = CollectionPager1.DataSourcePaged;
rpProducts.DataBind();
}
I am guessing you need two joins:
Select p.*, c.CategoryName, sc.CategoryName as SubCategoryName
from TBLPRODUCTS p left join
TBLCATEGORIES c
on p.CategoryId = c.CategoryId left join
TBLCATEGORIES sc
on c.SubCategoryId = sc.CateogryId
order by p.ProductID desc;
int id = 1;
string chain = "(";
SqlDataReader dr = SqlHelper.ExecuteReader(string.Format("SELECT a.Id as x, c.Id as y From Friends b INNER JOIN Users a ON b.SenderId = a.Id INNER JOIN Users c ON b.ReceiverId = c.Id WHERE (c.Id = {0} OR a.Id = {0}) AND State = '{1}'", id, "ok"));
if (dr.HasRows)
while (dr.Read())
if (id == int.Parse(dr["y"].ToString()))
chain += dr["x"].ToString() + ", ";
else
chain += dr["y"].ToString() + ", ";
if (chain.Length > 1)
chain = chain.Substring(0, chain.Length - 2) + ")";
else
chain = "(0)";
// Chain has for example => (2, 3, 4, 5) => which are the Ids for Users's Friends
string str = "SELECT TOP 20 a.*, b.UserName as Sender, c.UserName as Receiver, b.Avatar as SenderPic";
str += " FROM Events a INNER JOIN Users b ON a.SenderId = b.Id INNER JOIN Users c ON a.ReceiverId = c.Id ";
str += "WHERE SenderId IN ";
str += chain;
str += " OR ReceiverId IN";
str += chain;
str += " Order BY Id desc";
dr = SqlHelper.ExecuteReader(str);
chain considered as the user's friends .
does any one know how to execute this query with JOINS !? Thanks a lot ..
First, try to get rid of pushing parameter values with string.Format into SQL queries. That's a huge security issue.
To your query. I have to admit, I'm a bit lost in your string concatenation :-P, but if I'm right, you want to get the Events and some user information. As far as I can see, SenderId and ReciverId are already your ids. If so, you can completely remove the first SELECT and provide id (as parameter) directly into your second SQL statement like this (only the SQL):
Edit: Tom showed me the missing part (Status=Ok)
SELECT TOP(20)
a.*
,b.UserName as Sender
,c.UserName as Receiver
,b.Avatar as SenderPic
FROM Events a
INNER JOIN Users b ON a.SenderId = b.Id
INNER JOIN Users c ON a.ReceiverId = c.Id
WHERE
a.SenderId = #id
OR a.ReceiverId = #id;
Corrected version:
; WITH OkUsers AS (
SELECT
u.*
FROM Users u
JOIN Friends f ON u.Id = f.SenderId OR u.Id = f.RecipientId
WHERE
f.Status = 'Ok'
)
SELECT TOP(20)
a.*
,b.UserName as Sender
,c.UserName as Receiver
,b.Avatar as SenderPic
FROM Events a
INNER JOIN OkUsers b ON a.SenderId = b.Id
INNER JOIN OkUsers c ON a.ReceiverId = c.Id
WHERE
a.SenderId = #id
OR a.ReceiverId = #id;
SELECT distinct TOP(20) e.*, u1.UserName As Sender,
u2.UserName As Receiver, u1.Avatar AS SenderPic
FROM Friends f INNER JOIN Users u
ON(u.Id = f.SenderId OR u.Id = f.ReceiverId) AND State = 'ok'
INNER JOIN Events e
ON(f.SenderId = e.SenderId OR f.SenderId = e.ReceiverId
OR f.ReceiverId = e.SenderId OR f.ReceiverId = e.ReceiverId)
INNER JOIN Users u1
ON (e.SenderId = u1.Id)
INNER JOIN Users u2
ON (e.ReceiverId = u2.Id)
WHERE u.Id = #id;
I think that might help:
--step[1]
SELECT DISTINCT CASE
WHEN a.Id = 1 THEN c.ID
WHEN c.Id = 1 THEN a.Id
ELSE
0
END AS ID
INTO #OkUsers
From Friends b INNER JOIN Users a
ON b.SenderId = a.Id INNER JOIN Users c
ON b.ReceiverId = c.Id
WHERE (c.Id = #id OR a.Id = #id) AND State = 'Ok';
--step[2]
SELECT TOP 20 a.*, b.UserName as Sender, c.UserName as Receiver, b.Avatar as SenderPic
FROM Events a INNER JOIN Users b ON a.SenderId = b.Id INNER JOIN Users c ON a.ReceiverId = c.Id
INNER JOIN #OkUsers ON #OkUsers.ID = SenderId OR #OkUsers.ID = ReceiverId
EXCEPT
SELECT TOP 20 a.*, b.UserName as Sender, c.UserName as Receiver, b.Avatar as SenderPic
FROM Events a INNER JOIN Users b ON a.SenderId = b.Id INNER JOIN Users c ON a.ReceiverId = c.Id
--INNER JOIN #OkUsers ON #OkUsers.ID = SenderId OR #OkUsers.ID = ReceiverId
WHERE SenderId IN (SELECT ID FROM #OkUsers)
OR ReceiverId IN(SELECT ID FROM #OkUsers);
DROP TABLE #OkUsers;
Temp tables work good with very large volume of data.Otherwise you can use a memory table.
I have three tables, Professors, ProfessorStudent, Student.
I want all Professors + How many Students each Professor have.
I can do this:
context.ProfessorSet.Include("Student")
context.ProfessorSet.Include("Student").ToList() will read all three tables.
But i dont wanna get Student table, I want that Linq just get "Professor Table"+ "Count(*) ProfessorStudent Group By StudentId".
Its possible?
I do using this:
var c = from tag in contexto.ProfessorSet
select new
{
Tag = tag,
Count = tag.Student.Count
};
But generate this SQL:
SELECT
C.Id,
C.Nome,
C.C1
FROM
(SELECT
A.Id,
A.Nome,
(SELECT
COUNT(0)
FROM ProfessorStudant AS B
WHERE A.Id = B.ProfessorId
) AS [C1]
FROM Professor AS A)
I want this:
Select A.Id, Count(0) from Professor A
inner join ProfessorStudent B on A.Id = B.ProfessorId
Group By A.Id
from p in context.ProfessorSet
from s in p.Student
group s by s.StudentId into g
select new
{
Professor = p,
StudentCounts = from sc in g
select new
{
StudentId = sc.Key,
Count = sc.Group.Count()
}
}