Linq Subquery Where Clause - linq

I need some help with thsi linq query. It shoudl be fairly simple, but it is kicking my butt.
I need to use a subquery to filter out data from the main query, but every path I have tried to use results in failure.
The subquery by itself looks like this.
int pk = (from c in context.PtApprovedCertifications
where c.FkosParticipant == 112118 &&
(!excludedActionTypes.Contains(c.FkMLSosCodeActionType)) &&
c.EffectiveDate <= DateTime.Now &&
c.FkptApprovedCertificationVoidedBy == null
orderby c.EffectiveDate descending,c.PK descending
select c.PK).FirstOrDefault();
This works as expected but as you can see I plugged in the number 112118. This should be the primary key from main query.
The combined query I've been working on looks like this.
IQueryable<PtAMember> result = (from p in context.PtAMembers
where (p.FkptACertification == (from c in context.PtApprovedCertifications
where c.FkosParticipant == p.PtApprovedCertification.OsParticipant.PK &&
(!excludedActionTypes.Contains(c.FkMLSosCodeActionType)) &&
c.EffectiveDate <= DateTime.Now &&
c.FkptApprovedCertificationVoidedBy == null
orderby c.EffectiveDate descending, c.PK descending
select c.PK).FirstOrDefault()) &&
(p.LastName.ToLower().Contains(param.ToLower()) ||
p.FirstName.ToLower().Contains(param.ToLower()) ||
p.SocialSecurityNumber.Contains(param))
select p).Distinct().OrderBy(PtAMembers => PtAMembers.LastName).ThenBy(PtAMember => PtAMember.FirstName);
This results in an error though. Any help in solving this conundrum would greatly appreciated.
Thanks!

How about turning your subquery into a lookup function:
Func<int, int> pkLookup = n => (from c in context.PtApprovedCertifications
where c.FkosParticipant == n &&
(!excludedActionTypes.Contains(c.FkMLSosCodeActionType)) &&
c.EffectiveDate <= DateTime.Now &&
c.FkptApprovedCertificationVoidedBy == null
orderby c.EffectiveDate descending,c.PK descending
select c.PK).FirstOrDefault();
then using that in your main query.

Related

Add a Contains("string") functionality Azure Table LINQpad query?

OK, this doesn't work due to Azure Table query subset constraints:
var res = tcmarketnlog.Where(t => t.Level == level && t.Message.Contains("151207151510") && t.Timestamp >= start && t.Timestamp <= end).Take(1000);
The t.Message.Contains("151207151510") bombs. However, there must be some way to then search the results in LINQpad and select only the results with this string in the message.
For example, I could not coerce the result into a variable that was then queriable again with LINQ. Any tips?
If you can't use string.Contains on an Azure Table Queryable, you can still turn it into an Enumerable and then apply the additional filter to only show the results you want. However, it means that it will return all records that meet the other criteria over the network before then limiting them on the client side to only those rows where the Message field contains the specified string.
var res = tcmarketnlog.Where(t => t.Level == level && t.Timestamp >= start && t.Timestamp <= end).AsEnumerable().Where(t => t.Message.Contains("151207151510")).Take(1000);
Maybe message is null. Just check message null before contains. pls try this:
var res = tcmarketnlog.Where(t => t.Level == level
&& t.Message != null && t.Message.Contains("151207151510")
&& t.Timestamp >= start && t.Timestamp <= end).Take(1000);

Dynamic where condition in linq query expression

My Code :
IEnumerable<DataRow> whrRowEnum;
whrRowEnum = from r in dtInput.AsEnumerable()
where r.Field<string>("EMP_DEP") == "DEP1"
orderby EMP_DEP
select r;
The above code is working fine due to hard coded where condition, but In run-time I need to add multiple where condition in my linq query like r.Field("EMP_DEP") == "DEP1" && r.Field("EMP_ID") == "EMP1"
You can use lambda syntax to compose your query based on conditions:
IEnumerable<DataRow> query = dtInput.AsEnumerable();
if (condition1)
query = query.Where(r => r.Field<string>("EMP_DEP") == "DEP1");
if (condition2)
query = query.Where(r => r.Field<string>("EMP_ID") == "EMP1");
var whrRowEnum = query.OrderBy(r => r.Field<string>("EMP_DEP"));
Another option is adding conditions to query filter
whrRowEnum = from r in dtInput.AsEnumerable()
where (!condition1 || (r.Field<string>("EMP_DEP") == "DEP1")) &&
(!condition2 || (r.Field<string>("EMP_ID") == "EMP1"))
orderby EMP_DEP
select r;

LINQ Error The type is not supported in aggregation operations

I have LINQ code and I receive the following error: System.ServiceModel.FaultException: The type 'ObjectMgmt' is not supported in aggregation operations.
(from cinnost in edc.CinnostSOPs
where cinnost.LegislativneVyznamna == true &&
cinnost.ObjektId == objektid
select (from o in edc.PlanRealizaces
where o.CinnostSOPIdSOP == cinnost.IdSOP &&
o.DatumPlatnosti <= DateTime.Now &&
o.Provest == true &&
o.DatumProvedeni == null
orderby o.DatumPlatnosti descending
select new ObjectMgmt
{
Datum = (DateTime.Now.Date - o.DatumPlatnosti.Value).TotalDays
}).Max(m => m)).ToList<ObjectMgmt>();
The message speaks of an aggregate. The only aggregate I see is the Max call. This is the hint needed to debug the problem.
You care calculating the max of a sequence of ObjectMgmt instances which is obviously not possible. Change that to what you really meant.
The compiler error you get tells you that ObjectMgmt can not be used as the source of an aggregation. This happens because Max requires that the ObjectMgmt type implements IComparable.
After formatting your query to make it more readable it seems that you want to find the ObjectMgmt instance where Datum has the maximum value.
Since you already ordered the values descending by DatumPlatnosti you know that the ObjectMgmt instances are ordered by increasing Datum values. Therefore you don't need an aggregation at all. Just take the last element of the sequence (I would however order ascending and then take the first element).
(from cinnost in edc.CinnostSOPs
where cinnost.LegislativneVyznamna == true &&
cinnost.ObjektId == objektid
select (from o in edc.PlanRealizaces
where o.CinnostSOPIdSOP == cinnost.IdSOP &&
o.DatumPlatnosti <= DateTime.Now &&
o.Provest == true &&
o.DatumProvedeni == null
orderby o.DatumPlatnosti
select new ObjectMgmt
{
Datum = (DateTime.Now.Date - o.DatumPlatnosti.Value).TotalDays
}).First()).ToList<ObjectMgmt>();
Because your ObjectMgmt objects have only one property filled by query: Datum, change your Max call to get max of Datum, not the ObjectMgmt itself:
(from cinnost in edc.CinnostSOPs
where cinnost.LegislativneVyznamna == true &&
cinnost.ObjektId == objektid
select (from o in edc.PlanRealizaces
where o.CinnostSOPIdSOP == cinnost.IdSOP &&
o.DatumPlatnosti <= DateTime.Now &&
o.Provest == true &&
o.DatumProvedeni == null
orderby o.DatumPlatnosti descending
select new ObjectMgmt
{
Datum = (DateTime.Now.Date - o.DatumPlatnosti.Value).TotalDays
}).Max(m => m.Datum)).ToList<ObjectMgmt>();

Use Linq query to compare date only with DateTime field

I need to compare just the date only in a Linq query that involves a datetime field. However, the syntax below results in the following error message
The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
Does anyone know how to extract just the date out of a datetime field?
var duplicate = from a in _db.AgentProductTraining
where a.CourseCode == course.CourseCode &&
a.DateTaken.Date == course.DateTaken.Date &&
a.SymNumber == symNumber
select a;
It might seem a little roundabout, but you can use the SqlFunctions class' DateDiff method for doing this. Just pass in both values and use "Day" for finding the difference between them in days (which should be 0 if they are on the same day).
Like the following:
from a in _db.AgentProductTraining
where a.CourseCode == course.CourseCode &&
SqlFunctions.DateDiff("DAY", a.DateTaken, course.DateTaken) == 0 &&
a.SymNumber == symNumber
select a;
You can use EntityFunctions.TruncateTime() under the namespace System.Data.Objects
Ex.
db.Orders.Where(i => EntityFunctions.TruncateTime(i.OrderFinishDate) == EntityFunctions.TruncateTime(dtBillDate) && i.Status == "B")
Works like charm.
UPDATE
This function works only when you querying entities through LINQ. Do not use in LINQ-Object.
For EF6 use DbFunctions.TruncateTime() under System.Data.Entity namespace.
You can do it like bellow:
var data1 = context.t_quoted_value.Where(x => x.region_name == "Pakistan"
&& x.price_date.Value.Year == dt.Year
&& x.price_date.Value.Month == dt.Month
&& x.price_date.Value.Day == dt.Day).ToList();
you must use System.Data.Entity.DbFunctions.TruncateTime
try this
DateTime dt =course.DateTaken.Date;
var duplicate = from a in _db.AgentProductTraining
where a.CourseCode == course.CourseCode &&
a.DateTaken == dt &&
a.SymNumber == symNumber
select a;
if a.DateTaken contains Time also, then refer these links to modify your date.
The Date property cannot be used in LINQ To Entities.
Compare Dates using LINQ to Entities (Entity Framework)
'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported
http://forums.asp.net/t/1793337.aspx/1
This is how I ended by doing a similar Date search which I had to consider time (Hour and Minutes portion) also
from x in _db.AgentProductTraining
where
x.CreatedOn.Year == mydacourse.DateTakente.Year
&& x.CreatedOn.Month == course.DateTaken.Month
&& x.CreatedOn.Day == course.DateTaken.Day
&& x.CreatedOn.Hour == course.DateTaken.Hour
&& x.CreatedOn.Minute == course.DateTaken.Minute
select x;
Hey when I was building a query this below worked
DateTime date = Convert.ToDateTime(SearchText);
query = query.Where(x => x.Date.Month == date.Month
&& x.Date.Day == date.Day
&& x.Date.Year == date.Year);
// Let me know if this worked for you as it pulled the date that was searched for me
Take off the .Date
If the field is a DateTime it can be compared with ==
var duplicate = from a in _db.AgentProductTraining
where a.CourseCode == course.CourseCode &&
a.DateTaken == course.DateTaken &&
a.SymNumber == symNumber
select a;

In Operator in Linq

I tried to use the suggestion provided here for using In operator in linq but, i am not able to convert my requirement into LINQ statement.
Below is the SQL query which i need to convert to Linq
select *
from navigator_user_field_property
where user_id = 'albert'
and field_id in (
select field_id
from navigator_entity_field_master
where entity_id = 1
and use_type = 0)
order by field_id
I want this to be converted to a Efficient Linq.
Most of the answers deal with the predetermined list of string array which is not working in my case.
Thanks
Looks like a join to me:
var query = from navigator in db.NavigatorUserFieldProperties
where navigator.UserId == "albert"
join field in db.NavigatorEntityFieldMasters
.Where(f => f.EntityId == 1 && f.UseType == 0)
on navigator.FieldId equals field.FieldId
select navigator;
Note that this will return the same value multiple times if there are multiple fields with the same ID - but I suspect that's not the case.
You could do a more literal translation like this:
var query = from navigator in db.NavigatorUserFieldProperties
where navigator.UserId == "albert" &&
db.NavigatorEntityFieldMasters
.Where(f => f.EntityId == 1 && f.UseType == 0)
.select(f => f.FieldId)
.Contains(navigator.FieldId)
select navigator;
... and that may end up translating to the same SQL... but I'd personally go with the join.
Here is an efficient and readable LINQ query:
var fields =
from field in db.navigator_entity_field_masters
where field.entity_id == 1 && field.user_type == 0
select field;
var properties =
from property in db.navigator_user_field_properties
where property.user_id == "albert"
where fields.Contains(property.field)
select property;
Look mama!! Without joins ;-)

Resources