SQL to Linq Conversion - linq

I have sql as below
SELECT Q.MaterialID AS MaterialID, Q.ProductID AS ProductID, QB.Quantity AS Quantity,
Q.ParameterID AS ParameterID, SUM((Q.ParameterValue * Q.Quantity)/Q.TotalTonnes) AS ParameterValue
FROM #Quality Q
INNER JOIN #QuantityBreakdown QB
ON ((Q.MaterialID = QB.MaterialID) OR (Q.MaterialID IS NULL AND QB.MaterialID IS NULL))
AND ((Q.ProductID = QB.ProductID) OR (Q.ProductID IS NULL AND QB.ProductID IS NULL))
GROUP BY Q.MaterialID, Q.ProductID, ParameterID, QB.Quantity
conversion to LINQ..... struck at ???
var enumerable = from final in (from q in qualities
from qb in quantityBreakDowns
where q.ProductID == qb.ProductID && q.MaterialID == qb.MaterialID
select new
{
q.MaterialID,
q.ProductID,
q.ParameterID,
qb.Quantity,
ParameterValue = ((q.ProductID*q.Quantity)/q.TotalTonnes)
}
)
group final by new
{
final.MaterialID,
final.ProductID,
final.ParameterID,
???
}
into finalresult select finalresult;
Is there some other good way to do this.
Thanks

Ok solved this as:
from final in
(from q in qualities
from qb in quantityBreakDowns
where q.ProductID == qb.ProductID && q.MaterialID == qb.MaterialID
select new
{
q.MaterialID,
q.ProductID,
q.ParameterID,
qb.Quantity,
ParameterValue = ((q.ActualValue*q.Quantity)/q.TotalTonnes)
}
)
group final by new
{
final.MaterialID,
final.ProductID,
final.ParameterID,
final.Quantity
}
into finalresult
select new
{
finalresult.Key.MaterialID,
finalresult.Key.ProductID,
finalresult.Key.ParameterID,
finalresult.Key.Quantity,
ActualValue = finalresult.Sum(fq => fq.ParameterValue)
};

Related

i am trying to join 3 tables below is the code

var result = (from p in db.push_notifications
join nu in db.notification_recievers on p.id equals nu.push_notification_id
join nt in db.notification_types on p.notification_type_id equals nt.id
where (p.id == pushNotificationId && p.send_criteria == criteria && nu.delete_flag == false && p.delete_flag == false && nt.delete_flag == false)
select new NotificationList
{
conferenceId = p.conference_id,
pushNotificationId = p.id,
notificationId = nt.id,
notificationType = nt.notification_type,
nottificationDate = p.created_dt_tm,
criteria = (int)p.send_criteria,
notificationMessage = p.notification_msg,
userEmail=null,
userInterests = **getInterestNamesByPushNotificationId(p.id)**,
userEvents=null
}).Distinct();
public string getInterestNamesByPushNotificationId(int id)
{
string interests = string.Empty;
var query = from i in db.interests
join pn in db.notification_recievers
on i.id equals pn.interest_id
where pn.push_notification_id == id && pn.delete_flag == false
select new
{
name = i.name
};
foreach (var intr in query.Distinct())
{
if (interests == "")
{
interests = intr.name;
}
else
{
interests = interests + ", " + intr.name;
}
}
return interests;
}
this is throwing me error
LINQ to Entities does not recognize the method 'System.String
getInterestNamesBy PushNotification(Int32)' method, and this method
cannot be translated into a store expression.
The Entity Framework is trying to execute your LINQ clause on the SQL side, obviously there is no equivalent to 'getInterestNamesBy PushNotification(Int32)' from a SQL perspective.
You need to force your select to an Enumerable and then reselect your object using the desired method.
Not ideal but something like this should work - (not tested this so be nice).
var result = (from p in db.push_notifications
join nu in db.notification_recievers on p.id equals nu.push_notification_id
join nt in db.notification_types on p.notification_type_id equals nt.id
where (p.id == pushNotificationId && p.send_criteria == criteria && nu.delete_flag == false && p.delete_flag == false && nt.delete_flag == false)
select new { p=p, nu = nu, nt = nt }).AsEnumerable().Select( x => new NotificationList()
{
conferenceId = x.p.conference_id,
pushNotificationId = x.p.id,
notificationId = x.nt.id,
notificationType = x.nt.notification_type,
nottificationDate = x.p.created_dt_tm,
criteria = (int)x.p.send_criteria,
notificationMessage = x.p.notification_msg,
userEmail=null,
userInterests = getInterestNamesByPushNotificationId(x.p.id),
userEvents=null
}).Distinct();
i have done it this way
In my model
using (NotificationService nService = new NotificationService())
{
modelView = nService.DetailsOfNotifications(pushNotificationId, criteriaId).Select(x => new NotificationViewModelUI(x.conferenceId, x.pushNotificationId, x.notificationId, x.notificationType, x.nottificationDate, x.criteria, x.notificationMessage, x.userEmail, nService.getInterestNamesByPushNotificationId(x.pushNotificationId), nService.getIEventTitlesByPushNotificationId(x.pushNotificationId))).ToList();
}
public NotificationViewModelUI(int conferenceId, int pushNotificationId, int notificationId, string notificationType, DateTime dateTime, int criteria, string nMessage, string emailId = null, string interestNames = null, string eventTitles = null)
{
this.conferenceId = conferenceId;
this.pushNotificationId = pushNotificationId;
this.notificationId = notificationId;
this.notificationType = notificationType;
this.notificationDate = dateTime;
this.sendCriteria = (NotificationCriteria)criteria;
this.notificationMessage = nMessage;
this.emailId = NotificationCriteria.SpecificUser.Description() +"... "+ emailId;
this.interestNames = NotificationCriteria.UserByInterests.Description() + "... " + interestNames;
this.eventTitles = NotificationCriteria.UserByEvents.Description() + "... " + eventTitles;
}

how to pass string variable to linq select new {} section

Ii just want to make search functionality with linq with multiple ColumnNames that stored to session variable. I'm using one method:
public void FillGrid(string CommandName,string ColumnName, string SearchText)
That has three string variable that stores session value.
Now I just want to pass ColumnName with this query:
var query1 = (from p in db.Posts
join c in db.Categories on p.Category_id equals c.Id
join u in db.Users on p.User_id equals u.Id
where (p.ToUser_id == user_id || p.ToUser_id == null) && p.User_id != user_id
orderby p.Sent_Datetime descending
select new
{
Id = p.Id,
Title = p.Title,
Publisher = u.First_name + " " + u.Last_name,
ToUser = p.ToUser_id,
PublishDate = p.Sent_Datetime,
IsFile = p.IsFileAttached,
CategoryName = c.Category_name,
status_name = (from s in db.Status where (s.Id == p.status_id) select s.status_name).FirstOrDefault(),
Group_name = (from g in db.Groups where (g.Id == p.group_id) select g.Group_name).FirstOrDefault(),
FileSize = p.TotalFileSize,
ColumnName = Sesssion["ColumnName"].ToString()
}).Where(q => q.ColumnName.Contains(SearchText));
However, ColumnName does not give any text or it may be not part of this query i have to manually give column name because.
for multiple column i have, so i can not use this statement like:
.Where(q => q.Tile.Contains(SearchText));
this query works fine with single column. but there is multiple column i have so i have to set q.ColumnName from outer side.
I would do an extension method for that kind of things, building an expression for your predicate.
public static class Helper
{
public static IQueryable<T> FilterForColumn<T>(this IQueryable<T> queryable, string colName, string searchText)
{
if (colName != null && searchText != null)
{
var parameter = Expression.Parameter(typeof(T), "m");
var propertyExpression = Expression.Property(parameter, colName);
var searchExpression = Expression.Constant(searchText);
var containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var body = Expression.Call(propertyExpression, containsMethod, searchExpression);
var predicate = Expression.Lambda<Func<T, bool>>(body, new[] { parameter });
return queryable.Where(predicate);
}
else
{
return queryable;
}
}
}
usage in your case
var query1 = (from p in db.Posts
join c in db.Categories on p.Category_id equals c.Id
join u in db.Users on p.User_id equals u.Id
where (p.ToUser_id == user_id || p.ToUser_id == null) && p.User_id != user_id
orderby p.Sent_Datetime descending
select new
{
Id = p.Id,
Title = p.Title,
Publisher = u.First_name + " " + u.Last_name,
ToUser = p.ToUser_id,
PublishDate = p.Sent_Datetime,
IsFile = p.IsFileAttached,
CategoryName = c.Category_name,
status_name = (from s in db.Status where (s.Id == p.status_id) select s.status_name).FirstOrDefault(),
Group_name = (from g in db.Groups where (g.Id == p.group_id) select g.Group_name).FirstOrDefault(),
FileSize = p.TotalFileSize,
}).FilterForColumn(Sesssion["ColumnName"].ToString(), SearchText);

multiple conditions Linq extended

I need to consider multiple conditions to get value.
i mean if all conditions true that must give me a filtered answer.
Or one of them is true,rest are false...
so i need to write all possibilities??
if(a&b&c&d) else if(a&b&c) else if(a&c&d) else if(b&c&d) else if(a&b) else if (a&c)...etc ?? :))) Is there a shorter way to do this?
public List<ProductReqNoDate> GetRequestsQuery(string departmant, int reqStateID, string firstDate, string lastDate, string productName)
{
var db = new requestDBEntities();
bool dp = !string.IsNullOrEmpty(departmant);
bool pr = !string.IsNullOrEmpty(productName);
bool tm = !string.IsNullOrEmpty(firstDate) && !string.IsNullOrEmpty(lastDate);
bool rs = reqStateID > 0 ? true : false;
var query = (from r in db.requests
select new ProductReqNoDate
{
departmant = r.departmant,
reqNo = r.reqNo,
reqDate = r.reqDate,
productName = (from p in db.products where p.reqNo == r.reqNo select p.productName).FirstOrDefault()
}).ToList();
if (dp & pr & tm & rs)
{
var rState = (from ta in db.reqStates
where ta.reqStateID == reqStateID && ta.isActive == true
select ta.reqNo).ToList();
var prName = (from p in db.products where p.productName.Contains(productName) select p.reqNo).ToList();
DateTime dtfirstDate = Convert.ToDateTime(firstDate);
DateTime dtlastDate = Convert.ToDateTime(lastDate);
return query.Where(
r => rState.Contains(r.reqNo) //find by Request State
&& r.departmant == departmant //find by Departmant
&& (r.reqDate >= dtfirstDate && r.reqDate <= dtlastDate) //find by Date
&& prName.Contains(r.reqNo) //Find By Product Name
).ToList();
}
else if (dp & pr & tm) { /*return query.Where(...} */}
else if (pr & tm & rs) { /*return query.Where(...} */}
else if (dp & pr && rs) { /*return query.Where(...} */}
else if (dp & pr) { /*return query.Where(...} */}
//else if ...etc
}
Just add one Where condition at a time
public List<ProductReqNoDate> GetRequestsQuery(string departmant, int reqStateID, string firstDate, string lastDate, string productName)
{
var db = new requestDBEntities();
bool dp = !string.IsNullOrEmpty(departmant);
bool pr = !string.IsNullOrEmpty(productName);
bool tm = !string.IsNullOrEmpty(firstDate) && !string.IsNullOrEmpty(lastDate);
bool rs = reqStateID > 0 ? true : false;
var query = (from r in db.requests
select new ProductReqNoDate
{
departmant = r.departmant,
reqNo = r.reqNo,
reqDate = r.reqDate,
productName = (from p in db.products where p.reqNo == r.reqNo select p.productName).FirstOrDefault()
}).AsQueryable(); //AsQueryable is not always needed, but it shouldn't hurt and I don't feel like checking for this example.
if (dp)
{
query = query.Where(q => /*condition*/);
}
if (pr)
{
query = query.Where(q => /*condition*/);
}
if (tm)
{
query = query.Where(q => /*condition*/);
}
if (rs)
{
query = query.Where(q => /*condition*/);
}
return query.ToList();
}
You can build an expression with Expression.And like:
private Expression<Func<Request, bool>> GetPredicate(FilterDto filter)
{
Expression<Func<Request, bool>> predicate = r => r.ID == r.ID;
if (filter.Department.HasValue)
predicate = predicate.And(r => r.Department == filter.Department.Value);
if (filter.FirstDate.HasValue)
predicate = predicate.And(r => (r.reqDate >= filter.FirstDate.Value));
if (filter.LastDate.HasValue)
predicate = predicate.And(r => (r.reqDate <= filter.LastDate.Value));
/* ... */
return predicate;
}
Note: I put r => r.ID == r.ID here as first expression, just to have an expression to start with. This snippet does not fully cover your code, but I think it is enough as an example.
Use the expression in return query.Where(expression).ToList().

LINQ equivalent of this query

SELECT StudentHistoryId, StudentId, Grade, CreatedAt, ModifiedAt, ModifiedBy, Active
FROM TABLENAME TN
INNER JOIN ( SELECT StudentId, MAX(ModifiedAt) AS ModifiedAt FROM TABLENAME GROUP BY StudentId) M
ON TN.StudentId = M.StudentId AND TN.ModifiedAt = M.ModifiedAt
Here's a direct translaton:
var subquery = from tn in dc.TABLENAME
group tn by tn.StudentId into g
select new { StudentId = g.Key, ModifiedAt = g.Max(x => x.ModifiedAt) };
var query = from tn in dc.TABLENAME
join m in subquery
on new { tn.StudentId, tn.ModifiedAt }
equals new { m.StudentId, m.ModifiedAt }
select new
{
tn.StudentHistoryId,
tn.StudentId,
tn.Grade,
tn.CreatedAt,
tn.ModifiedAt,
tn.ModifiedBy,
tn.Active
};

Linq: Nested queries are better than joins, but what if you use 2 nested queries?

In her book Entity Framework Julie Lerman recommends using nested queries in preference to joins (scroll back a couple of pages).
In her example see populates 1 field this way, but what id you want to populate 2?
I have an example here where I would prefer to populate the Forename and Surname with the same nested query rather than 2 separate ones. I just need to know the correct syntax to do this.
public static List<RequestInfo> GetRequests(int _employeeId)
{
using (SHPContainerEntities db = new SHPContainerEntities())
{
return db.AnnualLeaveBookeds
.Where(x => x.NextApproverId == _employeeId ||
(x.ApproverId == _employeeId && x.ApprovalDate.HasValue == false))
.Select(y => new RequestInfo
{
AnnualLeaveDate = y.AnnualLeaveDate,
Forename = (
from e in db.Employees
where e.EmployeeId == y.EmployeeId
select e.Forename).FirstOrDefault(),
Surname = (
from e in db.Employees
where e.EmployeeId == y.EmployeeId
select e.Surname).FirstOrDefault(),
RequestDate = y.RequestDate,
CancelRequestDate = y.CancelRequestDate,
ApproveFlag = false,
RejectFlag = false,
Reason = string.Empty
})
.OrderBy(x => x.AnnualLeaveDate)
.ToList();
}
}
There's nothing wrong with your query, but you can write it in a way that is much simpler, without the nested queries:
public static List<RequestInfo> GetRequests(int employeeId)
{
using (SHPContainerEntities db = new SHPContainerEntities())
{
return (
from x in db.AnnualLeaveBookeds
where x.NextApproverId == employeeId ||
(x.ApproverId == employeeId && x.ApprovalDate == null)
orderby x.AnnualLeaveDate
select new RequestInfo
{
AnnualLeaveDate = x.AnnualLeaveDate,
Forename = x.Employee.Forename,
Surname = x.Employee.Surname,
RequestDate = x.RequestDate,
CancelRequestDate = x.CancelRequestDate,
ApproveFlag = false,
RejectFlag = false,
Reason = string.Empty
}).ToList();
}
}
See how I just removed your from e in db.Employees where ... select e.Forename) and simply replaced it with x.Employee.Forename. When your database contains the correct foreign key relationships, the EF designer will successfully generate a model that contain an Employee property on the AnnualLeaveBooked entity. Writing the query like this makes it much more readable.
I hope this helps.
try this
using (SHPContainerEntities db = new SHPContainerEntities())
{
return db.AnnualLeaveBookeds
.Where(x => x.NextApproverId == _employeeId ||
(x.ApproverId == _employeeId && x.ApprovalDate.HasValue == false))
.Select(y =>
{
var emp = db.Emplyees.Where(e => e.EmployeeId == y.EmployeeId);
return new RequestInfo
{
AnnualLeaveDate = y.AnnualLeaveDate,
Forename = emp.Forename,
Surname = emp.Surname,
RequestDate = y.RequestDate,
CancelRequestDate = y.CancelRequestDate,
ApproveFlag = false,
RejectFlag = false,
Reason = string.Empty
};
).OrderBy(x => x.AnnualLeaveDate).ToList();
}

Resources