MVC LINQ Not recognised method - c#

I've got a linq query extracting data from a table and I want to, being given a Date, convert it to week ( for example what week of the year it is ).
And the GetWeekofYear function:
private int GetWeekOfYear(DateTime d)
{
var cal = System.Globalization.DateTimeFormatInfo.CurrentInfo.Calendar;
return cal.GetWeekOfYear(new DateTime(d.Year, d.Month, 1), System.Globalization.CalendarWeekRule.FirstDay, System.DayOfWeek.Sunday);
}
In its current state, when I'm trying to test it ( using Postman / Fiddler ) I am getting the following error:
LINQ to Entities does not recognize the method 'Int32
GetWeekOfYear(System.DateTime)' method, and this method cannot be
translated into a store expression

The error occurs because Linq2Sql can not translate the GetWeekOfYear method to SQL.
Try the following:
select raw data instead into QuestionaireDetailsDTO
select new QuestionaireDetailsDTO() {
DepartureDate = transport.DepartureDate
};
add a getter to QuestionaireDetailsDTO that does the calculation:
public string Week => GetWeekOfYear(DepartureDate);
This way the conversion happens in memory instead of on the DB.
If the GetWeekOfYear method resides in a project that is not accessible by the consumer of the DTO, add a postprocessing step instead after you have selected the DTOs from the DB.
foreach (var result in query) {
result.Week = GetWeekOfYear(result.DepartureDate);
}

You can do this by using .AsEnumerable()
var query = from booking in context.BookingTables
join transport in context.TransportAllotments on booking.TransportAllotmentID equals transport.TransportAllotmentID
join passenger in context.Passengers on booking.BookingID equals passenger.BookingID
join result in context.QuestionaireResults on passenger.PassengerID equals result.PassengerID
join question in context.QuestionaireQuestions on result.QuestionaireQuestionID equals question.QuestionaireQuestionID
where transport.DepartureDate >= startDate && transport.DepartureDate <= endDate && booking.BookingID == id
.AsEnumerable()
select new QuestionaireDetailsDTO()
{
ID = booking.BookingID,
Date = transport.DepartureDate,
Question = question.QuestionText,
Week = GetWeekOfYear(transport.DepartureDate)
};
Hope it help.

As meintoined, this happents because LinqToSQL wasnt able to translate your method to SQL.
I think that answer from #GeorgPatscheider is not a best because you shouldn't change your data objects because some specific mechanisms of data access layer.
So, answer from #PhongDao is more cool, but him solution will download too many fields from database. You can change your code this way:
var query = from booking in context.BookingTables
join transport in context.TransportAllotments on booking.TransportAllotmentID equals transport.TransportAllotmentID
join passenger in context.Passengers on booking.BookingID equals passenger.BookingID
join result in context.QuestionaireResults on passenger.PassengerID equals result.PassengerID
join question in context.QuestionaireQuestions on result.QuestionaireQuestionID equals question.QuestionaireQuestionID
where transport.DepartureDate >= startDate && transport.DepartureDate <= endDate && booking.BookingID == id
// select only fields which we need
select new
{
ID = booking.BookingID,
Date = transport.DepartureDate,
Question = question.QuestionText,
DepartureDate = transport.DepartureDate
}
// retrieve data from DB
.ToArray()
// create items which you need
.Select(x=>
new QuestionaireDetailsDTO()
{
ID = x.ID,
Date = x.Date,
Question = x.Question,
Week = GetWeekOfYear(x.DepartureDate)
})
// forming results
.ToArray();

Related

Grouping on virtual (predefined) column in linq

I am trying to write a linq query for one of my dashboard which retrieves data based on some conditions. I want to display records count based on the different status available in my table.
Following is the SQL query in which I am trying to convert into Linq.
select count(id) cnt, 'Available' label from table where date = sysdate
Above query is returning below result in DB IDE. This is the result I want with linq
cnt label
0 Available
I've tried with following linq query but it is returning 0 count and hence result is not being retrieved.
var data = (from a in context
where a.date = System.DateTime.Now
group a in a.id into g
select new {
cnt = g.Count(),
label = 'Available'
}).ToList();
How do I achieve above mentioned result in linq. Your help will be appreciated.
Thanks
-------------EDIT----------------
Updated LINQ query
var data = (from a in context.TableA
where a.id = uniqueID
group a in a.id into g
select new {
cnt = g.Count(),
label = 'Available'
}).Concat(from a in context.TableB
where a.id = uniqueID
group a in a.id into g
select new {
cnt = g.Count(),
label = 'WIP'
}).ToList();
To count the number of elements matching a predicate in a linq query simply use the where clause:
var results =
from a in context
where a.date.Date == DateTime.Now.Date
&& a.id == someIdHere
select a;
var data = new {
count = results.Count(),
label = "Available"
};
Or, in extension method syntax (which I prefer):
var results = context.Where(a => a.date.Date == DateTime.Now.Date && a.id == someIdHere);
var data = new {
count = results.Count(),
label = "Available"
};
Also be careful when comparing a DateTime object with regards to what results you desire; comparing DateTime.Now to a date will likley return false since it will compare the time code as well, use the DateTime.Date property to obtain only the date from the object for the purposes of comparison.

SQL Query to Linq to Entities - C#

I have been trying to convert this SQL statement into a linq as i am trying to move the functionality into a program.
Here is the SQL statement
SELECT cust.sg_group_name AS customer,
(SELECT Sum(du.used_space)
FROM sg_groups AS clnt
LEFT JOIN client_disk_usage AS du
ON clnt.sg_group_id = du.sg_group_id
AND clnt.group_role_id = 3
WHERE clnt.parent_group_id = cust.sg_group_id
AND du.day_of_month = 15
AND du.month_of_year = 05
AND du.used_space_year = 2016) AS disk_usage
FROM sg_groups AS cust
WHERE cust.group_role_id = 2
ORDER BY cust.sg_group_name
Essentially the output is just a list with two columns
customer disk_usage
Customer1 136401537652
Customer2 42208008210
If possible i just want to convert this to a linq statement. I have tried putting the query into LinqPad, but it doesn't seem to want to convert from SQL to Linq (just comes up with a blank white page). I have had a crack at the query myself, but i either get something that doesn't work altogether, or an incorrect number of results.
If anyone has any suggestions that would be great!
disk_usage(Sub Query) is a bit Complicated Part. Converted over here. Try this out
var CoreList = (from clnt in EntityName.sg_groups
join du in EntityName.client_disk_usage
on new { GrpId = clnt.sg_group_id, RoleId = clnt.group_role_id } equals new { GrpId = du.sg_group_id, RoleId = 3 } into LJ
from RT in LJ.DefaultIfEmpty()
where du.day_of_month == 15 && du.month_of_year == 05 && du.used_space_year == 2016
select new {clnt, du, RT}
).ToList();
var CoreListSet = CoreList.Select(i=> new YourEntityClass
{
//Fetch the ParentGroupId & UsedSpace
}).ToList();
var CoreListComplete = (from cl in CoreListSet
join cust in EntityName.sg_groups
on cust.sg_group_id equals cl.parent_group_id).ToList();
Now get the sum of CoreListComplete & just implement the base Select Query in Linq!
Apologies for the delayed response. I've marked #Anil answer up as this is the one that helped me find the answer. You solution did work #Sathish but it can be accomplished in a single command. Here is my final solution. Many thanks for your help!
storeGridUsage = (
from cust in db.sg_groups
from client in db.sg_groups
join du in db.client_disk_usage on client.SG_GROUP_ID equals du.SG_GROUP_ID
where client.GROUP_ROLE_ID == 3
where client.PARENT_GROUP_ID == cust.SG_GROUP_ID && du.DAY_OF_MONTH == day && du.MONTH_OF_YEAR == month && du.USED_SPACE_YEAR == year
where cust.GROUP_ROLE_ID == 2
orderby cust.SG_GROUP_NAME
group new {cust, du} by cust.SG_GROUP_NAME
into g
select new StoreGridUsage
{
CustomerName = g.Key,
DiskUsageInBytes = g.Sum(o => o.du.USED_SPACE)
}).ToList();

Subquery in Linq query giving A query body must end with a select clause or a group clause

booked - below - should be the sum of the NumberBooked column from the Bookings table - which has a link to the TourDates table on the TourDateId.
However I'm getting the error A query body must end with a select clause or a group clause
Can anyone please help me fix this query?
Thank you,
Mark
var tours = from t in Tours
join d in TourDates on t.TourId equals d.TourId
where d.Date == dt
select new
{
t.TourId,
d.TourDateId,
booked = (from b in Bookings where d.TourDateId == b.TourDateId)
Select new {bk.Sum(b.NumberBooked()}
};
I believe this:
booked = (from b in Bookings where d.TourDateId == b.TourDateId) // oops
Select new {bk.Sum(b.NumberBooked()}
should be this:
booked = (from b in Bookings where d.TourDateId == b.TourDateId // move from here
select new {bk.Sum(b.NumberBooked()}) // to here
Note that I moved the end parenthesis ) so that it comes after the select, not after TourDateId
The closing round paranthesis ends the query which needs a select at the end.
Why don't you use method syntax? It is much better readable in this case. Also, a Select is optional with .Where and method syntax:
join d in TourDates on t.TourId equals d.TourId
where d.Date == dt
select new
{
t.TourId,
d.TourDateId,
booked = Bookings.Where(b => d.TourDateId == b.TourDateId)
.Sum(b => b.NumberBooked())
};
Note that i have removed the anonymous type since you just want the sum of that column
should be the sum of the NumberBooked column from the Bookings table -
which has a link to the TourDates table on the TourDateId.

add year in select clause linq

var query =
from u in this.Manager.GroupRecipients
join sz in this.Manager.Sub
on u.OD_ID equals sz.OD_Id into grpjoin
join z in this.Manager.Users
on u.ID equals z.ID
join m in this.Manager.Order_Details1
on u.OD_ID equals m.OD_Id
join o in this.Manager.Orders
on m.OrderId equals o.OrderId
join p in this.Manager.Products
on m.ProductId equals p.ProductId
from sz in grpjoin.DefaultIfEmpty()
where u.CampaignGroupId == groupid
select new DTO
{
FirstName = z.First_Name,
LastName = z.Last_Name,
Email = z.Email,
ProductName = p.Name,
PurchaseDate = (DateTime)o.OrderDate,
ExpiredDate = //stuck
};
I have this code and from the select clause, I can have a purchase date by using casting Datetime to the order date. However, I want to put expired date to be 1 year after purchasing. Is there any way to achieve the result? I was trying to put this code line
ExpiredDate = new DateTime(o.OrderDate).AddYears(1)
but an error saying that cannot convert from 'System.DateTime?' to 'long'
ExpiredDate = o.OrderDate.AddYears(1)
The original o.OrderDate will not be changed by this call, AddYears returns a new DateTime.
Your error is the result of calling a constructor that supposedly takes another DateTime object when no such constructor exists. You don't need a constructor call though, so just omit it.
I think the problem is DateTime() expects a long where you have given a another DateTime object. Check the different constructors of DateTime.
You can simply say
ExpiredDate = o.OrderDate.AddYears(1);

Get Count from one value in three table linq2sql select?

I just want the apartment complex count along with the other values. Only adding the count breaks the code. The error I get is "Sequence operators not supported for type 'System.String'." I have also tried changing apartCount to an int with no luck. Any help would be appreciated
using (var db = new DataClasses2DataContext())
{
var zips = (from s in db.ZipCodeServiceAvailabilities
join b in db.ZipCodeBoundaries on s.ZipCode equals b.ZipCode
join a in db.pdx_apart_views on s.ZipCode equals a.Zip_Code
where (s.IsServiced == 1 && b.Ordering % 10 == 0)
orderby b.ZipCode
select new
{
zipCode = b.ZipCode.Trim(),
latitude = b.Latitude,
longitude = b.Longitude,
apartCount = a.Apartment_complex.Count()
}).ToArray();
}
I think you miss group by clause in your query.
or you can use corolated sub query in select clause. please explain your question more

Categories