linq to sql: issue with linq query - visual-studio-2010

I have two tables
EmpInf
EmpId,
EmpName,
Salary,
DepartNumber.
Dept
DeptNo,
Deptname,
I also have a listview1 and dropdownlist1 which is bound to EmpInf.EmpName
While passing a particular query
FilterControl.DataClasses1DataContext obj = new DataClasses1DataContext();
protected void DropDownList1_SelectedIndexChanged1(object sender, EventArgs e)
{
var a = from r in obj.EmpInfs join s in obj.Dept1s on r.DeptNumber equals s.DeptNo where r.EmpName == "'" + DropDownList1.SelectedValue + "'" select s;
ListView1.DataSource = a;
ListView1.DataBind();
}
Whenever I select a particular name from a dropdownlist, it returns No data was returned. What particular code am I missing or is there any other error?

Put a breakpoint in SelectedIndexChanged1 and look at the value of SelectedValue to make sure DropDownList1.SelectedValue has the Employee name. You can also try DropDownList1.SelectedText.
string selected = DropDownList1.SelectedValue.ToString();
// e = employee | d = department
var query =
from e in obj.EmpInfs
join d in obj.Dept1s on e.DeptNumber equals d.DeptNo
where e.EmpName == "'" + DropDownList1.SelectedValue + "'"
select d;
Change this line:
where e.EmpName == "'" + DropDownList1.SelectedValue + "'"
to this one:
where e.EmpName == selected
OK, my last attempt here... Do this before databinding:
ListView1.DataSource = query.ToList();

Most likely the problem here is with your addition of the single quotes on the search criteria in your Where clause:
var a = from r in obj.EmpInfs
join s in obj.Dept1s on r.DeptNumber equals s.DeptNo
where r.EmpName == "'" + DropDownList1.SelectedValue + "'"
select s;
Assuming DropDownList1.SelectedValue is "Smith" then your generated sql will be along the lines of:
SELECT *
FROM <tables>
WHERE EmpName = ''Smith''
Notice the double single quotes. To double check this, put a breakpoint after your query is generated and then call .ToString() on it to get the equivalent TSQL. To fix this, remove the "'" from your LINQ query as that will be automatically added for string parameters:
var a = from r in obj.EmpInfs
join s in obj.Dept1s on r.DeptNumber equals s.DeptNo
where r.EmpName == DropDownList1.SelectedValue
select s;

Related

Pass date parameter to native query

A user can perform actions based on an occurrence value. When this value is equal to 'DAILY', I would like to retrieve all daily actions that have not been completed the last 24 hours.
The working SQL query:
SELECT distinct a.* FROM action as a LEFT OUTER JOIN history as h
ON a.id = h.action_id
AND h.user_id= <user> WHERE a.occurrence = 'DAILY' AND (h.id is NULL OR h.entry_date < TIMESTAMP 'yesterday')
The equivalent native query:
#Query(value =
"SELECT distinct a.* FROM action a "
+ "LEFT OUTER JOIN history h "
+ "ON a.id = h.action_id "
+ "AND h.user_id = :userId "
+ "WHERE a.occurrence='DAILY' AND (h.id IS NULL OR h.entry_date < :yesterday) ", nativeQuery = true)
public List<Action> findAllAvailableActions(#Param("userId") Long userId, #Param("yesterday") ZonedDateTime yesterday);
How it is called in my service :
ZonedDateTime today = ZonedDateTime.now(ZoneOffset.UTC);
ZonedDateTime yesterday = today.minus(1,ChronoUnit.DAYS);
Long userId = userDTO.getId();
List<Action> result = actionRepositoryCustom.findAllAvailableActions(userId, yesterday);
However, I do get the wrong results in my tests (actions that have already been completed are returned). I am afraid this is linked to the date parameter. The attribute entry_date is declared as ZoneDateTime in my entity. What am I doing wrong ?
hibernate : 5.2.4
You can't pass a ZonedDateTime into a native SQL query. You need to convert it to Calendar:
#Query(value =
"SELECT distinct a.* FROM action a "
+ "LEFT OUTER JOIN history h "
+ "ON a.id = h.action_id "
+ "AND h.user_id = :userId "
+ "WHERE a.occurrence='DAILY' AND (h.id IS NULL OR h.entry_date < :yesterday)", nativeQuery = true)
public List<Action> findAllAvailableActions(#Param("userId") Long userId, #Param("yesterday") Calendar yesterday);
And you can convert your ZonedDateTime this way:
public Calendar convertToDatabaseColumn(ZonedDateTime entityAttribute) {
if (entityAttribute == null) {
return null;
}
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(entityAttribute.toInstant().toEpochMilli());
calendar.setTimeZone(TimeZone.getTimeZone(entityAttribute.getZone()));
return calendar;
}
This approach is described here: link

simple join syntax not properly working

I'd like to show the number of records in the history table grouped by name of service
service(code,name)
history(id, code,....)
Please note that there is no relationship between the two table history and service, history stores the activity independently from the other tables
I have tested this sql query and it returns the expected result:
select s.name, count(*) from history c
join service s
on c.code=s.code
where c.state='INITIALE'
group by s.name
Actually, I'd like to write it in jpql, I did alike
Query query =entityManager.createQuery(" select s.name, count(*) from ServiceEntity s join"
+ " HistoryEntity c "
+ " where c.code=s.code and c.state='INITIALE'"
+ " group by c.name order by c.name"
);
I got this error : Path expected for join!....
Invalid path: 'c.code'....right-hand operand of a binary operator was null....unexpected end of subtree
Try this
Query query = entityManager.createQuery("select s.name, count(s) from ServiceEntity s, HistoryEntity c "
+ " where c.code = s.code and c.state = 'INITIALE'"
+ " group by s.name order by s.name"
);

jpql native query not setting parameter

#Repository
public interface GroupRepository extends JpaRepository<Group, String> {
//Other queries....
#Query(value = "with cte(group_id, parent_group_id, group_name) as( "
+ "select group_id, parent_group_id, group_name "
+ "from hea.hea_group "
+ "where group_id = ?1 "
+ "union all "
+ "select g.group_id, g.parent_group_id, g.group_name "
+ "from hea.hea_group g "
+ "inner join cte on cte.group_id = g.parent_group_id "
+ "where g.parent_group_id is not null "
+ ") select * from cte", nativeQuery = true)
List<Object> getChildGroups(String groupId);
}
Above is the query that I have written that should return the parent group and all of its children. The query does what it is suppose to do when I replace the ?1 with a hard coded group id value and change the method to have no parameters, but when I try to run it as above it returns nothing even though I'm passing in the exact same value that I was hard coding.
Below is the sql that is being generated by the query. When I replace the ? with a group id an run it on a test database it returns the results that it should.
with cte(group_id, parent_group_id, group_name) as( select
group_id,
parent_group_id,
group_name
from
hea.hea_group
where
group_id = ?
union
all select
g.group_id,
g.parent_group_id,
g.group_name
from
hea.hea_group g
inner join
cte
on cte.group_id = g.parent_group_id
where
g.parent_group_id is not null ) select
*
from
cte
The variables are zero based so ?0 is what you should use.

Linq query joining with a subquery

I am trying to reproduce a SQL query using a LINQ to Entities query. The following SQL works fine, I just don't see how to do it in LINQ. I have tried for a few hours today but I'm just missing something.
SELECT
h.ReqID,
rs.RoutingSection
FROM ReqHeader h
JOIN ReqRoutings rr ON rr.ReqRoutingID = (SELECT TOP 1 r1.ReqRoutingID
FROM ReqRoutings r1
WHERE r1.ReqID = h.ReqID
ORDER BY r1.ReqRoutingID desc)
JOIN ReqRoutingSections rs ON rs.RoutingSectionID = rr.RoutingSectionID
Edit***
I was able to get this working after looking at other examples including the one provided her by Miki. Here is the code that works for me:
First I created a query called route to hold the top record I needed to join to
var route = (from rr in context.ReqRoutings
where rr.ReqID == id
orderby rr.ID descending
select rr).Take(1);
I was then able to join to my requisitions table and the ReqRoutings lookup table
var header = (from h in context.ReqHeaders
join r in route on h.ID equals r.ReqID
join rs in context.ReqRoutingSections on r.RoutingSectionID equals rs.ID
where h.ID == id
select {ReqID = h.ID,
RoutingSection = rs.RoutingSection}
I am using Northwnd sample database
Customers,Orders,Employees table
Here I am getting top 1 order group by customer and order's employeeid
Please let me know If this is matching with your requirement or not
var ord = from o in NDC.Orders
orderby o.OrderID descending
group o by o.CustomerID into g
select new {CustomerID=g.Key,Order=g.OrderByDescending(s=>s.OrderID).First() };
var res1 = from o in ord
join emp in NDC.Employees
on o.Order.EmployeeID equals emp.EmployeeID into oemp
select new {Order=o.Order,employee=oemp };
Response.Write(res1.ToList().Count);
foreach (var order in res1)
{
Response.Write(order.Order.CustomerID + "," +
order.Order.OrderID + ","+
order.Order.EmployeeID+"<br/>");
}
// Above code is working .I have tried to convert your query to linq and replace your datacontext name with 'NDC'
var ord = from rr in NDC.ReqRoutings
orderby rr.ReqRoutingID descending
group rr by rr.ReqID into g
select new
{
ReqID = g.Key,
ReqRoutings = g.OrderByDescending(s => s.ReqRoutingID).First()
};
var res1 = from o in ord
join emp in NDC.ReqRoutingSections on o.ReqRoutings.RoutingSectionID
equals emp.RoutingSectionID into oemp
select new { ReqRoutings = o.ReqRoutings, employee = oemp };
Response.Write(res1.ToList().Count);
foreach (var order in res1)
{
Response.Write(order.ReqRoutings.ReqID + "," +
order.ReqRoutings.ReqRoutingID + "," +
order.ReqRoutings.RoutingSectionID + "<br/>");
}
Please let know if it is help you or not

LINQ Left Join with use of Where Or syntax

How can I migrate this stored procedure into LINQ
DECLARE #customerIDs TABLE (customerID INT)
DECLARE #c INT
if (#customerName != '')
BEGIN
INSERT INTO #customerIDs
select id from customer
where name like '%' + #customerName + '%'
SELECT #c = COUNT(*) FROM #customerIDs
END
else
SET #c = 0
-- Insert statements for procedure here
SELECT DISTINCT l.*, dbo.GetListOfBranches(l.id) as 'list_of_branches', dbo.GetTopLevelCustomer(cid.customerID) FROM [login] l
LEFT JOIN login_to_customer ltc ON ltc.login_id = l.id
LEFT JOIN #customerIDs cid ON cid.customerID = ltc.customer_id
WHERE
(#c = 0 OR ltc.customer_id = cid.customerID) AND
(l.surname LIKE '%' + ISNULL(#surname, l.surname) + '%') AND
(l.forename LIKE '%' + ISNULL(#forename, l.forename) + '%') AND
(user_type = ISNULL(#userType, user_type)) AND
(l.active = ISNULL(#active, l.active))
ORDER BY surname ASC
I have got this so far:
List<Int32> customerIds = new List<int>();
if (!String.IsNullOrEmpty(customerName))
{
CustomerDataContext custDataContext = new CustomerDataContext();
customerIds = (from a in custDataContext.Customers
where a.name.Contains(customerName)
select a.id).ToList<Int32>();
}
LoginDataContext dataContext = new LoginDataContext();
var query = (from t in dataContext.logins
join t2 in dataContext.login_to_customers on t.id equals t2.login_id into a
from subquery in a.DefaultIfEmpty()
select new { t, listOfBranches = dataContext.GetListOfBranches(t.id), topLevelCustomer = dataContext.GetTopLevelCustomer(t.id) });
I need would then do a
if (customerIds.Count() > 0)
{
query = query.Where(a => customerIds.Contains(a.t.customer_id))
}
but as I need to perform the distinct I cant have the customer_id column in the query. Is there a way to include the
LEFT JOIN #customerIDs cid ON cid.customerID = ltc.customer_id
WHERE
(#c = 0 OR ltc.customer_id = cid.customerID)
Within the LINQ?
Thanks,
Richard

Resources