Using Linq to find a very specific pattern from Oracle - linq

I'm replacing a php application using .net and I wish to look for a very specific PATTERN of string in some instances.
I've been using the below code to replace this SQL statement
WHERE FOO LIKE %SMITH%
query = query.Where(x => x.PARTIES.Any(y => y.PNAME.ToUpper().Contains(predicate.PartyName.ToUpper())));
This works fine however I've been advised I need to also be able to look for a special pattern like the below
WHERE FOO LIKE %"%SMITH%"%
That would find something like the below.
"CAPTAIN JOHN V.SMITH"
I've attempted to use this code in order to replicate the query but it return 0 hits
string s = string.Format("%\"%SMITH%\"%", predicate.PartyName);
query = query.Where(x => x.PARTIES.Any(y => y.PNAME.Contains(s)));
Any aid would be appreciated.

Looks like this works
query = query.Where(x => x.PARTIES.Any(y =>
(y.PNAME.StartsWith("\"")
&&
y.PNAME.EndsWith("\"")
&&
y.PNAME.Contains(predicate.PartyName) )));

Related

Need some help on a somewhat complex LINQ query

I have this query that does what I want which is to return true if any of the materials is comparable in the material groups list.
mgroup.MaterialGroups.Select(x => x.Materials
.Any(m => Convert.ToBoolean(m.Comparable)))
.Any(x => x.Equals(true))
What I would like to add to this query is to also include this one.
mgroup.Materials.Any(m => Convert.ToBoolean(m.Comparable));
How can I combine mgroup and it's materialgroups together in the query so I can select both of their Materials? Thanks.
EDIT - After fighting with LINQ for awhile I broke down and just combined as
mgroup.Materials.Any(m => Convert.ToBoolean(m.Comparable) ||
mgroup.MaterialGroups.Select(x => x.Materials
.Any(c => Convert.ToBoolean(c.Comparable)))
.Any(x => x.Equals(true)))
It works as expected but it's horribly long and it's embedded in an Asp.net MVC view to makes things even worse. If anyone can simplify this that would be amazing.
P.S.- If you are wondering why I added the extra .Any(x => x.Equals(true) at the end it's because without it the query returns an IEnumerable of bools instead of bool.
IEnumerable<Material> allMaterials =
mgroup.Materials.Concat(
mgroup.MaterialGroups.SelectMany(group => group.Materials));
bool result = allMaterials.Any(m => Convert.ToBoolean(m.Comparable));

Entity Framework: Best way to query for a set of dates using Linq

I have a set of unique DateTimes (without time portion) that the user can select from the user interface. This is not only a range like "LastWeek" or "LastMonth". The user can selcet every single day he wants.
What might be the best way to Linq-query in EntityFramework for matching results? I have a table Foo with an Attribute CreatedAt, which stores information with time portion. Of course I dont want to check the CreatedAt-Property on client side, SqlServer should do the job for me.
I think it should be someting like:
var query = _entities.Foo.Where(x => x.UserID == user.ID);
if (selectedDates.IsNullOrEmpty() == false)
query = query.Where(x => x.CreatedAt 'IsIn' selectedDates);
or:
foreach (var date in selectedDates)
query = query.Where(x => x.CreatedAt.Year == date.Year && x.Month == date.Month && x.Day == date.Month) //but of course here I have the problem that I have to use the 'Or'-Operator, not 'And'.
How can I accomplish this?
You can use EntityFunctions.TruncateTime() to perform a truncation of the date on the server. Then something along the lines of this should work.
query = query.Where(x => selectedDates.Contains(EntityFunctions.TruncateTime(x));
You can call the Contains extension method on selectedDates. Entity Framework 4.0 will understand this and will translate it to an IN operator in SQL:
if (selectedDates.IsNullOrEmpty() == false)
query = query.Where(x => selectedDates.Contains(x.CreatedAt));
Try query = query.Where(x => selectedDates.Contains(x.CreatedAt));

How to convert a LINQ query from query syntax to query method

Linq and EF4.
I have this Linq query in query syntax I would like convert into query method.
Are you able to do it? I tried more tha 2 hours without success :-(
Thanks for your time
CmsContent myContentObj = (from cnt in context.CmsContents
from categoy in cnt.CmsCategories
where categoy.CategoryId == myCurrentCategoryId && cnt.ContentId == myCurrentContentId
select cnt).Single();
My original answer selected the wrong item. It's a bit more complicated than what I had (which Ani has posted). Here's what I believe is an equivalent query however and should perform better:
CmsContent myContentObj =
context.CmsContents
.Where(cnt => cnt.ContentId == myCurrentId
&& cnt.CmsCategories
.Any(categoy => categoy.CategoryId == myCurrentCategoryId))
.Single();
Here is a non-direct translation that I believe performs the same task in much less code:
var myContentObj = context.CmsContents.Single(
x => x.ContentId == myCurrentContentId &&
x.CmsCategories.Any(y => y.CategoryId == myCurrentCategoryId)
);
Here's how the C# compiler actually does it, with some help from .NET Reflector to verify:
var myContentObj = context
.CmsContents
.SelectMany(cnt => cnt.CmsCategories,
(cnt, categoy) => new { cnt, categoy })
.Where(a => a.categoy.CategoryId == myCurrentCategoryId
&& a.cnt.ContentId == myCurrentContentId)
.Select(a => a.cnt)
.Single();
Essentially, the 'nested' from clauses results in a SelectMany call with a transparent identifier (an anonymous-type instance holding the 'parent' cnt and the 'child' categoy). The Where filter is applied on the anonymous-type instance, and then we do another Select projection to get back the 'parent'. The Single call was always 'outside' the query expression of course, so it should be obvious how that fits in.
For more information, I suggest reading Jon Skeet's article How query expressions work.

How do I merge two LINQ statements into one to perform a list2.Except(list1)?

Currently, I have the following LINQ queries. How can I merge the two queries into one. Basically, write a LINQ query to bring back the results I'd get from
IEnumerable<int> deltaList = people2010.Except(allPeople);
except in a single query.
var people2010 = Contacts.Where(x => x.Contractors
.Any(d => d.ContractorsStatusTrackings
.Any(date => date.StatusDate.Year >= 2010)))
.Select(x => x.ContactID);
var allPeople = Contacts.Where(x => x.Contractors
.Any(m => m.ContactID == x.ContactID))
.Select(x=> x.ContactID);
Thanks!
Why can you not just do Except as you are doing? Don't forget that your people2010 and allPeople variables are just queries - they're not the data. Why not just use them as they are?
If that's not acceptable for some reason, please give us more information - such as whether this is in LINQ to Object, LINQ to SQL etc, and what's wrong with just using Except.
It sounds like you're just looking for a more elegant way to write your query. I believe that this is a more elegant way to write your combined queries:
var deltaList =
from contact in Contacts
let contractors = contact.Contractors
where contractors.Any(ctor => ctor.ContractorStatusTrackings
.Any(date => date.StatusDate.Year >= 2010))
&& !contractors.Any(m => m.ContactID == contact.ContactID)
select contact.ContactID

Lost with LINQ and Expressions

I'm trying to write a LINQ query on some objects where I need to only do a select if a filter value is set.
Is there a way to "change" the query dynamically to only do a select if this is set.
Use where to find the items of interest, e.g.:
collection.Where(i => PassesFilter(i)).Select(i => i.InterestingValue);
var query = Somthing().Where(x => x.IsSomethingYouAlwaysFilterBy);
if(FilterValueIsSet(filterValue))
{
query = query.Where(x => x.Property == filterValue)
}
I'm not sure I understand your question, but you can use predicate builder. Predicate Builder example here

Resources