LINQ Query returns nothing - linq-to-sql

Why is this query returns 0 lines?
There is a record matching the arguments.
SomeDataContext db = new SomeDataContext(ConnString);
return db.Deafkaw.Where(p =>
(p.SomeDate1 >= aDate &&
p.SomeDate1 <= DateTime.Now) &&
(p.Year == aYear && p.IsSomething == false)
).ToList();
Am i missing something?
On the Table Deafkaw
SomeDate1 = 20/4/2010 11:32:17
Year = 2010
IsSomething = False
...besides other columns im not interested in conditions.
I need SomeDate1 between the dates i give IsSomething = False and Year = 2010.

You aren't assigning the result to anything so it is being discarded. Try this:
var results = db.Deafkaw.Where(p =>
(p.ImerominiaKataxorisis >= aDate &&
p.ImerominiaKataxorisis <= DateTime.Now) &&
(p.Year == etos && p.IsYpodeigma == false)
).ToList();
Update: you changed the question so now I'm not sure that this is the correct answer. Can you post the code where you call this method?

It is difficult to answer your question without any additional information. Checking the following points may help you to find the problem:
If you remove Where clause and write Deafkaw.ToList(), what do you get?
What is the value of aDate and etos?
Can you double check the condition? Do you require that all subconditions hold at the same time? Are there any such data if you print entire DeaFkaw data structure?
Can you try removing some sub-conditions to see if that gives you some results?

Try
Deafkaw.Where(p => (p.ImerominiaKataxorisis >= aDate && p.ImerominiaKataxorisis <= DateTime.Now &&
p.Year == etos && p.IsYpodeigma == false)).ToList();

Use SQL profiler. Look at the sql query that is generated. Run the sql query manually and see if you get back any records.

Related

Compare datetime in peewee sql Python

Apparently, I could not compare the date in the peewee SQL.
START_DATE = datetime.datetime(2015, 7, 20, 0, 0, 0)
customer_records = Customers.select().\
join(Current_Insurers, on=(Customers.current_insurer == Current_Insurers.id)).\
switch(Current_Insurers).\
join(Insurers, on=(Current_Insurers.insurer == Insurers.id)).\
where(Customers.pol_type == "PC" & \
Current_Insurers.effective_date == START_DATE )
Where Customers, Current_Insurers, Insurers are three class. The result is always 0 records. But if I removed the datetime condition from the sql and compare as follows
customer_records = Customers.select().\
join(Current_Insurers, on=(Customers.current_insurer == Current_Insurers.id)).\
switch(Current_Insurers).\
join(Insurers, on=(Current_Insurers.insurer == Insurers.id)).\
where(Customers.pol_type == "PC"
for r in customer_records:
if(r.current_insurer.effective_date == START_DATE):
print(r.policy_id)
Surprisingly we can compare now and print out customers.
What do I need to do to add the datetime condition in the peewee sql?
Many thanks,
Apparently, I could not compare the date in the peewee SQL.
That's completely incorrect. Do you honestly think that the library would be that broken??
The problem is Python operator precedence. You need to wrap the equality expressions with parentheses. So you where clause should look like this instead:
where((Customers.pol_type == "PC") & \
(Current_Insurers.effective_date == START_DATE))
Additionally, it's typically only necessary to call switch() when you have multiple joins to a single model.
Put together, your query should be:
query = (Customers
.select()
.join(Current_Insurers, on=(Customer.current_insurer == Current_Insurers.id))
.join(Insurers, on=(Current_Insurers.insurer == Insurer.id))
.where(
(Customers.pol_type == "PC") &
(Current_Insurers.effective_date == START_DATE)))
I came here because I had the same problem abd subsequently the same question.
The cause of my issue was that mariaDB was stripping the milliseconds when the original insert was done and python/peewee was passing in the milliseconds in the predicate on the later update. Very frustrating.

LINQ query records based on date array

I have a table (I am using Entity Model) and filtered that table using LINQ query which is working fine.
Now I want to filter the records on the basis of array of dates. I am not able to implement IN clause on array of dates
filteredList = leadsNewAndScheduled.Where(lead =>
(LeadTypeIDs.Contains(lead.TYPE_ID.ToString()) ||
LeadTypeIDs == string.Empty) &&
(priorityIDs.Contains(lead.PRIORITY_ID.ToString()) ||
priorityIDs == string.Empty) &&
(((lead.EXPIRED_ON <= dateExpiry ||
Convert.ToDateTime(lead.EXPIRED_ON) == DateTime.Today.Date) &&
lead.STATUS_ID == (int)Enumerations.LeadStatus.New) ||
lead.STATUS_ID == (int)Enumerations.LeadStatus.Active) &&
(lead.START_TIME IN (arrAppointmentDates))
).ToList();
I want your help in following
(lead.START_TIME IN (arrAppointmentDates))
Thanks in advance.
Use Predicate Builder
Write your query without the date condition like
var query = leadsNewAndScheduled.Where(lead =>
(LeadTypeIDs.Contains(lead.TYPE_ID.ToString()) ||
LeadTypeIDs == string.Empty) && ....
Then write
var predicate = PredicateBuilder.False<Lead>();
foreach (DateTime date in dates)
{
DateTime temp = date;
predicate = predicate.Or (p => p.START_TIME == temp);
}
var result = query.Where(predicate).ToList(); // Don't call ToList() earlier
However please note that if you're using Entity Framework you need to call AsExpandable() on the entity set before applying predicates on it like so:
return objectContext.Products.AsExpandable().Where (predicate);
I solved this problem while declaring list of dates and then applying contains clause in LINQ query.
example:
//list of dates.
List<DateTime> arrAppointmentDates;
//change in query
arrAppointmentDates.Contains(Convert.ToDateTime(lead.START_TIME).Date)

Use of custom expression in LINQ leads to a query for each use

I have the following problem: In our database we record helpdesk tickets and we book hours under tickets. Between those is a visit report. So it is: ticket => visitreport => hours.
Hours have a certain 'kind' which is not determined by a type indicator in the hour record, but compiled by checking various properties of an hour. For example, an hour which has a customer but is not a service hour is always an invoice hour.
Last thing I want is that the definitions of those 'kinds' roam everywhere in the code. They must be at one place. Second, I want to be able to calculate totals of hours from various collections of hours. For example, a flattened collection of tickets with a certain date and a certain customer. Or all registrations which are marked as 'solution'.
I have decided to use a 'layered' database access approach. The same functions may provide data for screen representation but also for a report in .pdf . So the first step gathers all relevant data. That can be used for .pdf creation, but also for screen representation. In that case, it must be paged and ordered in a second step. That way I don't need separate queries which basically use the same data.
The amount of data may be large, like the creation of year totals. So the data from the first step should be queryable, not enumerable. To ensure I stay queryable even when I add the summation of hours in the results, I made the following function:
public static decimal TreeHours(this IEnumerable<Uren> h, FactHourType ht)
{
IQueryable<Uren> hours = h.AsQueryable();
ParameterExpression pe = Expression.Parameter(typeof(Uren), "Uren");
Expression left = Expression.Property(pe, typeof(Uren).GetProperty("IsOsab"));
Expression right = Expression.Constant(true, typeof(Boolean));
Expression isOsab = Expression.Equal(Expression.Convert(left, typeof(Boolean)), Expression.Convert(right, typeof(Boolean)));
left = Expression.Property(pe, typeof(Uren).GetProperty("IsKlant"));
right = Expression.Constant(true, typeof(Boolean));
Expression isCustomer = Expression.Equal(Expression.Convert(left, typeof(Boolean)), Expression.Convert(right, typeof(Boolean)));
Expression notOsab;
Expression notCustomer;
Expression final;
switch (ht)
{
case FactHourType.Invoice:
notOsab = Expression.Not(isOsab);
final = Expression.And(notOsab, isCustomer);
break;
case FactHourType.NotInvoice:
notOsab = Expression.Not(isOsab);
notCustomer = Expression.Not(isCustomer);
final = Expression.And(notOsab, notCustomer);
break;
case FactHourType.OSAB:
final = Expression.And(isOsab, isCustomer);
break;
case FactHourType.OsabInvoice:
final = Expression.Equal(isCustomer, Expression.Constant(true, typeof(Boolean)));
break;
case FactHourType.Total:
final = Expression.Constant(true, typeof(Boolean));
break;
default:
throw new Exception("");
}
MethodCallExpression whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { hours.ElementType },
hours.Expression,
Expression.Lambda<Func<Uren, bool>>(final, new ParameterExpression[] { pe })
);
IQueryable<Uren> result = hours.Provider.CreateQuery<Uren>(whereCallExpression);
return result.Sum(u => u.Uren1);
}
The idea behind this function is that it should remain queryable so that I don't switch a shipload of data to enumerable.
I managed to stay queryable until the end. In step 1 I gather the raw data. In step 2 I order the data and subsequently I page it. In step 3 the data is converted to JSon and sent to the client. It totals hours by ticket.
The problem is: I get one query for the hours for each ticket. That's hundreds of queries! That's too much...
I tried the following approach:
DataLoadOptions options = new DataLoadOptions();
options.LoadWith<Ticket>(t => t.Bezoekrapport);
options.LoadWith<Bezoekrapport>(b => b.Urens);
dc.LoadOptions = options;
Bezoekrapport is simply Dutch for 'visitreport'. When I look at the query which retrieves the tickets, I see it joins the Bezoekrapport/visitreport but not the hours which are attached to it.
A second approach I have used is manually joining the hours in LINQ, but that does not work as well.
I must do something wrong. What is the best approach here?
The following code snippets are how I retrieve the data. Upon calling toList() on strHours in the last step, I get a hailstorm of queries. I've been trying for two days to work around it but it just doesn't work... Something must be wrong in my approach or in the function TreeHours.
Step 1:
IQueryable<RelationHoursTicketItem> HoursByTicket =
from Ticket t in allTickets
let RemarkSolved = t.TicketOpmerkings.SingleOrDefault(tr => tr.IsOplossing)
let hours = t.Bezoekrapport.Urens.
Where(h =>
(dateFrom == null || h.Datum >= dateFrom)
&& (dateTo == null || h.Datum <= dateTo)
&& h.Uren1 > 0)
select new RelationHoursTicketItem
{
Date = t.DatumCreatie,
DateSolved = RemarkSolved == null ? (DateTime?)null : RemarkSolved.Datum,
Ticket = t,
Relatie = t.Relatie,
HoursOsab = hours.TreeHours(FactHourType.OSAB),
HoursInvoice = hours.TreeHours(FactHourType.Invoice),
HoursNonInvoice = hours.TreeHours(FactHourType.NotInvoice),
HoursOsabInvoice = hours.TreeHours(FactHourType.OsabInvoice),
TicketNr = t.Id,
TicketName = t.Titel,
TicketCategorie = t.TicketCategorie,
TicketPriority = t.TicketPrioriteit,
TicketRemark = RemarkSolved
};
Step 2
sort = sort ?? "TicketNr";
IQueryable<RelationHoursTicketItem> hoursByTicket = GetRelationHours(relation, dateFrom, dateTo, withBranches);
IOrderedQueryable<RelationHoursTicketItem> orderedResults;
if (dir == "ASC")
{
orderedResults = hoursByTicket.OrderBy(sort);
}
else
{
orderedResults = hoursByTicket.OrderByDescending(sort);
}
IEnumerable<RelationHoursTicketItem> pagedResults = orderedResults.Skip(start ?? 0).Take(limit ?? 25);
records = hoursByTicket.Count();
return pagedResults;
Step 3:
IEnumerable<RelationHoursTicketItem> hours = _hourReportService.GetRelationReportHours(relation, dateFrom, dateTo, metFilialen, start, limit, dir, sort, out records);
var strHours = hours.Select(h => new
{
h.TicketNr,
h.TicketName,
RelationName = h.Relatie.Naam,
h.Date,
TicketPriority = h.TicketPriority.Naam,
h.DateSolved,
TicketCategorie = h.TicketCategorie == null ? "" : h.TicketCategorie.Naam,
TicketRemark = h.TicketRemark == null ? "" : h.TicketRemark.Opmerking,
h.HoursOsab,
h.HoursInvoice,
h.HoursNonInvoice,
h.HoursOsabInvoice
});
I don't think your TreeHours extension method can be converted to SQL by LINQ in one go. So are evaluated on execution of each constructor of the row, causing a 4 calls to the database in this case per row.
I would simplfy your LINQ query to return you the raw data from SQL, using a simple JOIN to get all tickets and there hours. I would then group and filter the Hours by type in memory. Otherwise, if you really need to perform your operations in SQL then look at the CompiledQuery.Compile method. This should be able to handle not making a query per row. I'm not sure you'd get the switch in there but you may be able to convert it using the ?: operator.

Select Date from a Datetime value

I want to select Date part from a DateTime value using Linq to Sql or sql lambda.
Here is my scenario.
dbContext.PurchaseOrders.Where(r => r.ReqDate == DateTime.Now).ToList();
Here ReqDate is a DateTime field. I want to select all the purchase orders for today.
It shouild be as simple as just using the Date property in DateTime:
UPDATE: From the 3rd error in the comments I see that ReqDate is A Nullable<DateTime>. Try using the Value property to access the underlying DateTime object:
dbContext.PurchaseOrders.Where(r => r.ReqDate.Value.Date == DateTime.Now.Date)
.ToList();
EDIT
Alternatively, you could try the not-so-pretty option:
dbContext.PurchaseOrders.Where(r => r.ReqDate.ToString("yyyy-MM-dd") ==
DateTime.Now.ToString("yyyy-MM-dd"))
.ToList();
Just convert your DateTime objects to a string formatted to contain the date only.
I have an answer that will return a list. Long way I know but I could not find a solution anywhere.
I hope this save someone else the frustration. I have been searching and searching to find an answer to this issue.
It does a group by on datetime to return a list of dates with no time. In my case it was to load a combo box of dates to choose from.
var mADates = from ta in db.AM_Assignments
orderby ta.Assignment_DTM
group ta by ta.Assignment_DTM.Date;
List<DateTime> dtx = new List<DateTime>();
foreach (var dt in mADates)
{
dtx.Add(Convert.ToDateTime(dt.Key.ToShortDateString()));
}
return dtx;
Use the Subtract method.
dbContext.PurchaseOrders.Where(r => DateTime.Now.Subtract(r.ReqDate).Days == 0).ToList();
try this:
dbContext.PurchaseOrders.Where(r => r.ReqDate.Date == DateTime.Today).ToList();
.Date creates a 00:00:00 time so time is not compared
dbContext.PurchaseOrders.Where(r => r.ReqDate.Date == DateTime.Now.Date).ToList();
There are some LINQ2SQL functions that imitate native SQL ones. One of them - truncation of time from DateTime? or DateTimeOffset?.
var today = DateTime.Now.Date;
dbContext.PurchaseOrders.Where(r => DbFunctions.TruncateTime(r.ReqDate).Value == today).ToList();
More compact version of #Angus 's code
var mADates = from ta in db.AM_Assignments
orderby ta.Assignment_DTM
group ta by ta.Assignment_DTM.Date;
return mADates.Select(dt => Convert.ToDateTime(dt.Key.ToShortDateString())).ToList();

LINQ subquery IN

I'm a newbie with the IQueryable, lambda expressions, and LINQ in general. I would like to put a subquery in a where clause like this :
Sample code :
SELECT * FROM CLIENT c WHERE c.ETAT IN (
SELECT DDV_COLUMN_VAL FROM DATA_DICT_VAL
WHERE TBI_TABLE_NAME = 'CLIENT' AND DD_COLUMN_NAME = 'STATUS'
AND DDV_COLUMN_VAL_LANG_DSC_1 LIKE ('ac%'))
How do I translate this in LINQ ?
var innerquery = from x in context.DataDictVal
where x.TbiTableName == myTableNameVariable
&& x.DdColumnName == "Status"
&& x.DdbColumnValLangDsc1.StartsWith("ac")
select x.DdvColumnVal;
var query = from c in context.Client
where innerquery.Contains(c.Etat)
select c;
from c in db.Client
where (from d in db.DataDictVal
where d.TblTableName == "Client"
&& d.DDColumnName == "Status"
&& dd.DdvColumnValLandDsc1.StartsWith("ac"))
.Contains(c.Etat)
select c;
If you are new to Linq, you absolutely need two essential tools. The first is a tool that converts most T-SQL statements to Linq called Linqer (http://www.sqltolinq.com/). This should take care of the query in your question. The other tool is LinqPad (http://www.linqpad.net/). This will help you learn Linq as you practice with queries.
I often use Linqer to convert a T-SQL query for me, and then use LinqPad to fine tune it.
Same example with Linq method syntax:
var innerquery = dbcontext.DataDictVal
.where(x=> x.TbiTableName == myTableNameVariable
&& x.DdColumnName == "Status"
&& x.DdbColumnValLangDsc1.StartsWith("ac"))
.select(x=>x.DdvColumnVal)
var query = dbcontext.Client
.where( c=>innerquery.Contains(c.Etat))
Note:
Am providing this answer, because when i searched for the answer, i couldn’t find much answer which explains same concept in the method syntax.
So In future, It may be useful for the people, those who intestinally searched method syntax like me today.
Thanks
karthik