Getting a full month report after searching a date in LINQ - c#

I need to generate a full month report base on some criteria. The first condition is- I am taking a anonyms Date from user and after checking all the condition it will generate full month report.
I tried to generate the report but this is returning a day wise report. Everything is fine except the month. Please help me to do this.
[HttpGet("inner-join/{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public IActionResult GetReport(DateTime id)
{
try
{
IEnumerable<BTBPending> objBTBPendingList = _unitOfWork.BTBPending.GetAll(includeProperties: "ProformaInvoice,ContractList,SupplierList,CountryList,ItemList,BuyerList,StyleList,TradeTermList,ErpRemarksList,StatusList,LcNoList,UdAmendList");
IEnumerable<ProformaInvoice> objProformaInvoiceList = _unitOfWork.ProformaInvoice.GetAll(includeProperties: "ActualContract,ContractList,SupplierList,CountryList,ItemList,BuyerList,StyleList,TradeTermList");
var query = objBTBPendingList
.Where(x => x.LcOpenDate == id)
.Where(x => x.CountryListId == 26)
.Where(x => x.StatusListId == 12 || x.StatusListId == 13 || x.StatusListId == 14)
.Join(objProformaInvoiceList,
btbPending => btbPending.ContractListId,
pi => pi.ContractListId,
(btbPending, pi) => new
{
LcNo = btbPending.LcNoList,
Value = btbPending.PiValue,
ContractNo = pi.ContractList,
Buyer = pi.BuyerList,
PiNo = pi.PINo,
Supplier = pi.SupplierList,
Item = pi.ItemList
}).ToList();
return Ok(query);
}
catch (Exception ex)
{
return StatusCode(500, "Internal Server Error, Please Try Again Leter!");
}
}

You have to make condition for the month, you are doing on the date. so do like this.
.Where(x => x.LcOpenDate.Month == id.Month && x.LcOpenDate.Year == id.Year)
Here I am assuming both id and LcOpenDate are from the same timezones.
As per the comment, LcOpenDate is DateTime?, so you need to do this.
LcOpenDate.Value.Month and LcOpenDate.Value.Year

DateTime gives your a full date and time and looks something like
2022-11-11 11:44:53 PM
What is likely going on is that when you are storing the data in the database, you are ommitting the time. Something like this:
var date = new DateTime(now.Year, now.Month, now.Day)
// 2022-11-11 12:00:00 AM
This is the only way x.LcOpenDate == id would work. Otherwise it would only return items with the open date at the exact time you provided up to the millisecond.
Try this instead:
.Where(x => x.LcOpenDate.Year == id.Year && x.LcOpenDate.Month == id.Month)
Additionally, if you are on .net 6+ you can use DateOnly and TimeOnly

Related

Wrong results fetching data based on date with Linq and SQL

I am trying to get a list with some data from SQL using Linq. The results in list are based on date which the user inputs.
My code for getting the list
TimologioList = Dao.SearchTimologiaNotSendToMydata(apoDateEdit.DateTime,
eosDateEdit.DateTime.Date.AddDays(1).AddMilliseconds(-1),
MainDoc.Xrisi,
DefaultDiasafistis.DiasafistisDefault,
apestalmenaCheckEdit.Checked);
public List<Timologio> SearchTimologiaNotSendToMydata(DateTime apoDate, DateTime eosDate, string xrisi, Diasafistis diasafistis, bool apestalmenaTimologia)
{
List<Timologio> timologia = db.Timologio
.Where(p => (p.Imerominia >= apoDate && p.Imerominia <= eosDate)
&& (p.Xrisi == xrisi && p.Diasafistis == diasafistis)
&& (!p.IsYpodeigma.HasValue || !p.IsYpodeigma.Value)
&& p.ArithmosTimologiou != 0)
.OrderByDescending(p => p.Imerominia).ToList();
return timologia;
}
The two variables have values apoDate = 1/1/2022 12:00:00 and eosdate = 31/1/2022 11:59:59.
When I run this query, it returns another result which has a date of 1/2/2022 and I don't understand why.
Values of the date variables:
SQL data:
Results in the program:
I am using DateTime.Date.AddDays(1).AddMilliseconds(-1) because I found that it gives more precise values in the date

ASP.NET MVC Filtering results by date returns 0 results

I am trying to filter the results of a database query by date. The user will input a date value as a string and then I use that string to compare to the date of every query result to try to find a match, however there is never a match, even when I know one exists.
Query and filtering:
var documents = from s in db.Documents
select s;
if (!String.IsNullOrEmpty(searchString))
{
documents = documents.Where(s => s.Order_Date.ToString().Contains(searchString) ||
s.Comment.Contains(searchString));
}
It should be noted that if the searchString is found in the Comment column, then it works fine. But again, there is never a match for date.
In the SQL table that the app connects to the column Order_Date is of date datatype (not datetime). However in the model Order_Date is a DateTime variable because as far as I'm aware C# does not have just date.
Here is an example of the problem:
Result
What am I doing wrong?
You are comparing 11/8/2004 with s.Order_Date.ToString(). This approach has several problems:
Maybe s.Order_Date contains 2004-08-11 but when you do s.Order_Date.ToString() it turns to month-day-year date format 8/11/2004 (instead day-month-year) and 8/11/2004 != 11/8/2004
What happens if user enters 11/08/2004 ? 11/08/2004 != 11/8/2004. User will don't understand why they are no results.
If you want to search by date the best solution is to use a date entry control. If for your UX is important to enter date in a text control instead a date control then you should to tokenize text and try to identify dates on text, convert to date and use a date to compare on linq expression.
DateTime? search_date_start = tokenize_and_extract_date_start(searchString)
DateTime? search_date_end = tokenize_and_extract_date_end(searchString)
String? search_comment = remove_dates_from_search_string(searchString)
documents =
documents
.Where(s =>
search_date_start == null ||
s.Order_Date >= search_date_start)
)
.Where(s =>
search_date_end == null ||
s.Order_Date <= search_date_end)
)
.Where(s =>
search_comment == null ||
s.Comment.Contains(search_comment)
);
I figured it out using Jonathan's comment. This is the simplest way to do it:
if (!String.IsNullOrEmpty(searchString))
{
try
{
var test = DateTime.Parse(searchString);
documents = documents.Where(s => s.Order_Date == test);
}
catch (FormatException e)
{
documents = documents.Where(s => s.Comment.Contains(searchString));
}
}

Combined to date and time fields into one when both datetime stamps

I am trying to combine the date and time part of a table so that I can set appointments correctly I was wondering if someone could help me my syntax is not being compiled
public List<Appointment> getAppointments (DateTime AppointmentDate)
{
List<Appointment> query = _sourceEntities.Appointments.Where(a => a.ApptDate == AppointmentDate && a.ClientID==6).ToList();
return _sourceEntities.Appointments.Select(r =>
{
var newAppointment = new Appointment();
DateTime date = new DateTime(r.ApptDate.Year, r.ApptDate.Month, r.ApptDate.Day, r.ApptTime.Hour, r.ApptTime.Minute, r.ApptTime.Second);
newAppointment.ApptDate = date;
return newAppointment();
});
}
The error is hapening here return newAppointment(); I am not sure why its saying method name expected I want to have all the fields of the old list but also this new combined date time field.
Here is the example of the data to best explain
https://i.imgur.com/rCtx0lt.png
Edit 2
The _sourceEntites is decalred heree at the top of the class
public class SourceContext
{
public SMBASchedulerEntities _sourceEntities = new SMBASchedulerEntities();
public static List<Appointment> getAppointments(DateTime apptDate)
List<Appointment> query = _sourceEntities.Appointments.Where(a => a.ApptDate == AppointmentDate && a.ClientID==6).ToList();
return _sourceEntities.Appointments.Select(r =>
{
var newAppointment = new Appointment();
DateTime date = new DateTime(r.ApptDate.Year, r.ApptDate.Month, r.ApptDate.Day, r.ApptTime.Hour, r.ApptTime.Minute, r.ApptTime.Second);
newAppointment.ApptDate = date;
return newAppointment();
});
}
newAppointment is an object variable, by using ('s the compiler treats newAppointment as a method, that is what the error message states. Removing the ('s should solve the problem.
An alternative way to return the result would be
public List<Appointment> getAppointments (DateTime AppointmentDate)
{
List<Appointment> query = _sourceEntities.Appointments.Where(a => a.ApptDate == AppointmentDate && a.ClientID==6).ToList();
return _sourceEntities.Appointments.Select(r => new Appointment
{
newAppointment.ApptDate = ew DateTime(r.ApptDate.Year, r.ApptDate.Month, r.ApptDate.Day, r.ApptTime.Hour, r.ApptTime.Minute, r.ApptTime.Second);
//map other variables here
});
}
The problem with your code is in the line: return newAppointment();. You are treating the object newAppointment like a method when you add the parenthesis after it. Instead, you can just do:
return newAppointment;
A slightly simpler approach would be to create a new Appointment in your Select statement. This will return an IEnumerable of Appointment objects, which we can the call ToList() on before returning. I also included a .Where() clause to match what you had in your query. You can remove that line if it's not needed.
public static List<Appointment> getAppointments(DateTime apptDate)
{
return _sourceEntities.Appointments
.Where(a => a.ApptDate == apptDate && a.ClientID == 6) // Remove if not needed
.Select(r =>
new Appointment
{
ApptDate = new DateTime(r.ApptDate.Year, r.ApptDate.Month, r.ApptDate.Day,
r.ApptTime.Hour, r.ApptTime.Minute, r.ApptTime.Second)
})
.ToList();
}
One other thing to note is that you are doing an equality comparison on the two date objects, so you will only be getting appointments for the exact date and time of the argument passed in. In case you want to get all the appointments for the day, you can just use the Date portion of the DateTime objects for comparison:
// Compare the Date portion of the argument to get all appointments for that day
.Where(a => a.ApptDate.Date == appointment.Date && a.ClientID == 6)

C#: Return any item that matches the condition

I have a method like this:
public ActionResult ShowAvailableSpots(int Id, DateTime ArrivalDate, DateTime LeaveDate)
{
var query2 = db.Spots
.Where(c => db.Reservations.Any(r =>
DbFunctions.TruncateTime(ArrivalDate) <= DbFunctions.TruncateTime(r.ArrivalDate) && DbFunctions.TruncateTime(LeaveDate) <= DbFunctions.TruncateTime(r.ArrivalDate)
|| DbFunctions.TruncateTime(ArrivalDate) >= DbFunctions.TruncateTime(r.LeaveDate)
)).ToList();
ViewBag.StartingDate = ArrivalDate;
ViewBag.EndingDate = LeaveDate;
ViewBag.AvailableSpots = query2;
ViewBag.CampingSpotId = new SelectList(query2, "CampingSpotId", "SpotName");
return View();
}
It determines wether any of the reservations match the date criteria. If they don't match, then the list with Campingspots is returned.
The problem is, that it is returning ALL spots or NONE spots instead of just the spots that are available. This is due to the .Any method. How can I filter out the campingspots that are not available?
Try something like this:
var query2 = db.Spots.Where(c => db.Reservations
.Where(r => c.CampingSpotId == r.CampingSpotId)
.All(r => DbFunctions.TruncateTime(LeaveDate) <= DbFunctions.TruncateTime(r.ArrivalDate)
|| DbFunctions.TruncateTime(ArrivalDate) >= DbFunctions.TruncateTime(r.LeaveDate))
)).ToList();
The inner Where statement says we're only checking the reservations that apply to that camping spot, and the All statement checks to make sure that every reservation for that campsite is outside the window we're interested in.

LINQ Where clause with four &&

I'm trying to create an LINQ Query with 4 arguments in the Where clause. It's a Windows 8 App project and I'm using an SQLite Database. (SQLite implementation )
Here's the code snippet:
public List<FinancialListBoxExpenseItem> retrieveExpenseItems(int month, int year, bool isPaid, StaticResources.FrequencyEnum frequencyEnum)
{
List<FinancialListBoxExpenseItem> tmpList = null;
connection.RunInTransaction(() =>
{
var items = from s in connection.Table<FinancialListBoxExpenseItem>()
where (s.expenseDateNextPayment.Month == month)
&& (s.expenseDateNextPayment.Year == year)
&& (s.expensePaidForCurrentPeriod == isPaid)
&& (s.expenseFrequencyTypeEnum == frequencyEnum)
select s;
tmpList = items.ToList<FinancialListBoxExpenseItem>();
});
return tmpList;
}
It throws a NotSupportedAction: Member access failed to compile expression Exception
I have no idea what does this mean and how i'm supposed to fix it.
Edit: it works without the where clause therefore the error must be related to this where clause part of the code
Probably .Month is not supported by your LINQ provider. You'll have to work around that, possibly by creating specialized columns for the month and the year.
This is how i solved the problem:
public List<FinancialListBoxExpenseItem> retrieveExpenseItems(int month, int year, bool isPaid, StaticResources.FrequencyEnum frequencyEnum)
{
List<FinancialListBoxExpenseItem> tmpList = new List<FinancialListBoxExpenseItem>();
connection.RunInTransaction(() =>
{
var items = from s in connection.Table<FinancialListBoxExpenseItem>()
let convertedDate = (DateTime)s.expenseDateNextPayment
where (convertedDate.Month == month)
&& (convertedDate.Year == year)
&& (s.expensePaidForCurrentPeriod == isPaid)
&& (s.expenseFrequencyTypeEnum == frequencyEnum)
select s;
tmpList = items.ToList();
});
return tmpList;
}
In my App I was getting a NotSupportedException when running a LINQ query, and the details of the exception showed
Member access failed to compile expression
As this thread let me know, the issued seemed to be caused by a DateTime variable that was being referenced in the query. Outside of finding a StackOverflow thread like this one to point you in the right direction, I'm not sure how anyone is supposed to figure that out on their own, but for me, changing the way I was writing the query fixed the problem.
This syntax was throwing the "NotSupportedException":*
IEnumerable<Foo> foos = connection.Table<Foo>().Where(foo => foo.Timestamp.Year == year);
Switching to this syntax worked just fine:
IEnumerable<Foo> foos = connection.Table<Foo>().Where(
delegate(Foo foo)
{
return (foo.Timestamp.Year == year);
});

Categories

Resources