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

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);

Related

How to pass an external parameter to LINQ where clause in CRM

I have a LINQ query which works fine as for stand alone lists but fails for CRM
var lst = new List<bool?>();
lst.Add(null);
lst.Add(true);
lst.Add(false);
bool IsWet = false;
var newlst = from exch_HideVoiceSignature in lst where
(((exch_HideVoiceSignature!=null && exch_HideVoiceSignature==false
|| exch_HideVoiceSignature== null) )&& !IsWet) select exch_HideVoiceSignature;
newlst.Dump();
var question = from q in exch_questionSet where ((q.exch_HideVoiceSignature != null
&& q.exch_HideVoiceSignature.Value == 0 )|| q.exch_HideVoiceSignature == null )
&& !IsWet select q.exch_HideVoiceSignature;
question.FirstOrDefault().Dump();
As you can see I can pass the variable IsWet to LINQ query for a standard list fine and get values for first list. But when I execute the same for second list, I get the following error
Invalid 'where' condition. An entity member is invoking an invalid property or method
The CRM LINQ provider won't support the evaluation you attempting. It only supports evaluation of where criteria is evaluating an entity field.
That's not a problem. Since you want the LINQ query to only use the where clause if IsWet is false (correct me if I'm wrong on that.) So we simply do the evaluation to determine if the where clause should be added or not. Then execute your query.
var question = from q in exch_questionSet
select q.exch_HideVoiceSignature;
if (!IsWet)
{
question.Where(x => ((x.exch_HideVoiceSignature != null
&& x.exch_HideVoiceSignature.Value == 0) || x.exch_HideVoiceSignature == null));
}
question.FirstOrDefault().Dump();
I am constantly confronted with that problem.
Try to "detach" (for example call .ToArray()) your query (while it is "clear") from CRM and then filter query using external parameter. This should help.
var question =
(from q in exch_questionSet
where (
(q.exch_HideVoiceSignature != null && q.exch_HideVoiceSignature.Value == 0 ) ||
q.exch_HideVoiceSignature == null )
select q.exch_HideVoiceSignature
).ToArray().Where(q => !IsWet);
question.FirstOrDefault().Dump();
UPDATE
If you are using IsWet flag to control blocks of conditions (enable and disable them from the one point in the code) then probably you may be interested in class named PredicateBuilder which allows you to dynamically construct predicates.
Just because I had an existing query with lot of other joins etc. and I wanted to pass this additional parameter to it I ended up using a var statement which dumps the rows to a list and applies the where clause in the same statement
bool IsWet =true ;
var question = ...existing query ...
select new {
...existing output ...,
Wet =q.exch_HideVoiceSignature != null &&
q.exch_HideVoiceSignature.Value == 119080001,
Voice = q.exch_HideVoiceSignature == null ||
(q.exch_HideVoiceSignature != null &&
q.exch_HideVoiceSignature.Value == 119080000) ,
}
;
var qq = IsWet ?
question.ToList().Where(X=> X.Wet ) :
question.ToList().Where(X=> X.Voice );
qq.FirstOrDefault().Dump();

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;

Linq: Handle empty table

How do you handle an empty table/NullReference in LINQ?
I have the following Linq statement in my code:
List<FeaturedTrack> features = _db.FeaturedTracks.Where(f => (f.FeatureStartDate >= DateTime.Now && f.FeatureEndDate <= DateTime.Now) ||
(f.FeatureStartDate == null && f.FeatureEndDate == null))
.ToList<FeaturedTrack>();
My table is currently empty, now I know this table won't be empty but it got me wondering about how to handle the NullReference error in case it is.
I've tried this:
int test = _db.FeaturedTracks.Count();
if (test > 0)
{
...
}
However my code breaks on the first line, so how do I check the table is empty before running the statement?

Linq Subquery Where Clause

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.

Resources