LINQ doesnt work for japanese words - c#

I have list of items defined as: IQueryable and I need go trough and find if any of the fields contain a specific word. When I use foreach and loop trough it and use .Contains, then everything works fine. The problem is that I need to use LINQ and .Boost, because some of the fields have higher priority when I find words in them.
When I use LINQ I get no results. For most languages LINQ works fine, but for Japanese words it does not. Can someone explain me why foreach with .Contains works fine and LINQ with .Where does not?
Code example:
foreach (var item in itemList)
{
if ((item.PageHeadings != null && item.PageHeadings.Contains(keyword)) ||
(item.PageName != null && item.PageName.Contains(keyword)) ||
(item.MetadataDescription != null &&
item.MetadataDescription.Contains(keyword)) ||
(item.MetadataKeywords != null &&
item.MetadataKeywords.Contains(keyword)) ||
(item.ExpandedContent != null &&
item.ExpandedContent.Contains(keyword)))
{
list.Add(item.Name);
}
}
LINQ example:
list.AddRange(from item in itemList where (item.PageHeadings != null
&& item.PageHeadings.Contains(keyword).Boost(BoostPageHeading))
|| (item.PageName != null && item.PageName.Contains(keyword).Boost(BoostPageName))
|| (item.MetadataDescription != null && item.MetadataDescription.Contains(keyword).Boost(BoostMetadataDescription))
|| (item.MetadataKeywords != null && item.MetadataKeywords.Contains(keyword).Boost(BoostMetadataKeywords))
|| (item.ExpandedContent != null && item.ExpandedContent.Contains(keyword).Boost(BoostExpandedContent)) select item.Name);
Thanks
UPDATE:
Example of phrase: 天窓使用例

Related

Null checker in LINQ

I have resData object with Courses listItem and Error property. I have checked all the Courses list item Error properties and all of them are null.
However, when I check in the following, it returns true.
I wonder what I am missing?
if(resData.Courses.Select(x => x.Error != null && x.Error.Length > 0).Count() > 0)
{
Console.WriteLine("Error");
}
It's because you are using a Select, you are projecting your collection, not applying a condition, you should use Where instead, or use an overload of Count method:
if(resData.Courses.Count(x => x.Error != null && x.Error.Length > 0) > 0)
And as #Chris pointed out, it's better if you use Any to avoid enumerate the entire list:
if(resData.Courses.Any(x => x.Error != null && x.Error.Length > 0))

LINQ equivalent of SQL NOT IN statement

I have a query that in T-SQL it is
SELECT *
FROM rpm_scrty_rpm_usr ru
WHERE ru.inact_ind = 'N'
AND email_id IS NOT NULL
AND wwid IS NULL
AND LTRIM(RTRIM (email_id)) <> ''
AND dflt_ste_id NOT IN (25,346,350,352,353,354,355,357,358,366,372,411)
When I have been converting it to LINQ, I have everything except the "NOT IN"
var querynonSystem = (from ru in Rpm_scrty_rpm_usrs
where ru.Inact_ind == "N" && ru.Email_id != null && ru.Wwid == null && ru.Email_id.Trim() != ""
&& ru.Dflt_ste_id != 25
select ru).Count();
I did temporarily put in this line && ru.Dflt_ste_id != 25
However I need to have AND dflt_ste_id NOT IN (25,346,350,352,353,354,355,357,358,366,372,411)
I am seeing a lot of different code like
this lambda where !(list2.Any(item2 => item2.Email == item1.Email))
Then var otherObjects = context.ItemList.Where(x => !itemIds.Contains(x.Id));
For my linq query, how can I do this Not In in simple manner?
You can use Contains with !. In addition, if you just want to count rows, you can use Count.
var ids = new List<int> {25, 346, 350, 352, 353, 354, 355, 357, 358, 366, 372, 411};
var querynonSystem = XXXcontext.Rpm_scrty_rpm_usrs.Count(x =>
x.Inact_ind == "N" &&
x.Email_id != null &&
x.Wwid == null &&
x.Email_id.Trim() != "" &&
!ids.Contains(x.Dflt_ste_id));
From comment: if you want to retrieve all, you can still use Where and Select.
var querynonSystem = XXXcontext.Rpm_scrty_rpm_usrs.Where(x =>
x.Inact_ind == "N" &&
x.Email_id != null &&
x.Wwid == null &&
x.Email_id.Trim() != "" &&
!ids.Contains(x.Dflt_ste_id)).Select(x => x).ToList();
FYI: you cannot call Rpm_scrty_rpm_usrs table class to query. Instead, you need DbContext or some other repository.
There is no "not in" operator unless the type of the query is the same as the type you want to filter against (in which case you could use except). Here it is not. You're working on an IEnumerable and you want to filter on it's ID so a list of int. The where with lambda and contains is your best bet and WILL be translated to an in on the SQL side by most providers.
var FilterIds = new List<int>{1,2,3,4,344,3423525};
var querynonSystem = (from ru in Rpm_scrty_rpm_usrs
where ru.Inact_ind == "N" && ru.Email_id != null && ru.Wwid == null && ru.Email_id.Trim() != ""
&& ru.Dflt_ste_id != 25
select ru)
// Use this
.Where(ru=>!FilterIds.Any(id=>ru.dflt_ste_id ==id))
// Or this
.Where(ru=>!FilterIds.Contains(ru.dflt_ste_id))
.Count();

Is it proper to negate an entire if statement to check for null values?

I am somewhat of a beginner programmer. What I am trying to do here is to check that if there is a time, if it is selected, and if that time is equivalent to the other. If that is all true then I want to skip the block of code under it. Here is the code example:
if (currentGVR.Round_Start_Time)
{
if (tr.StartLunchDateTime != null && currentGVR.Round_Start_Lunch && roundedStart == roundedStartL)
// skip
else
{
key = tr.TransactionID;
TransactionRecords[key]["Start_DateTime"] = roundedStart;
}
}
I thought about using an OR operator, but I can see where an error would occur if there was no time to compare to. Using the AND operator avoids this dilemma here.
So the overall question is, is it proper coding to negate all of the conditions to get the correct result, e.g. if (!( cond's )), and also, would this be the best way to check if there is a value to compare with before actually comparing it in C# and otherwise? The times can be null (or do not exist) in some records. Any recommendations?
I'd negate all those conditions and switch the && to || so it's more quickly evident under what conditions the code will (or will not) execute.
Plus (in my experience), you don't typically see an empty if block with all the code under the else.
if (tr.StartLunchDateTime == null || !currentGVR.Round_Start_Lunch || roundedStart != roundedStartL)
{
key = tr.TransactionID;
TransactionRecords[key]["Start_DateTime"] = roundedStart;
}
The statement
if (tr.StartLunchDateTime != null && currentGVR.Round_Start_Lunch && roundedStart == roundedStartL){
// skip
}
else
{
key = tr.TransactionID;
TransactionRecords[key]["Start_DateTime"] = roundedStart;
}
is equivalent to
if (!(tr.StartLunchDateTime != null && currentGVR.Round_Start_Lunch && roundedStart == roundedStartL))
{
key = tr.TransactionID;
TransactionRecords[key]["Start_DateTime"] = roundedStart;
}
else {
// skip
}
This can be further simplified because
!(tr.StartLunchDateTime != null &&
currentGVR.Round_Start_Lunch &&
roundedStart == roundedStartL)
Is the same as
(!(tr.StartLunchDateTime != null) ||
!(currentGVR.Round_Start_Lunch) ||
!(roundedStart == roundedStartL))
or
(tr.StartLunchDateTime == null ||
!currentGVR.Round_Start_Lunch ||
roundedStart != roundedStartL)
See DeMorgan's Laws.
if (someLongCondition)
{ }
else
{
doStuff();
}
is equivalent to this:
if (!someLongCondition)
{
doStuff();
}
So yeah, you can just negate your whole condition:
if (!(tr.StartLunchDateTime != null && currentGVR.Round_Start_Lunch && roundedStart == roundedStartL))
{ … }
But you can also pull the negation in (applying De Morgan's laws) and write it like this:
if (tr.StartLunchDateTime == null || !currentGVR.Round_Start_Lunch || roundedStart != roundedStartL)
{ … }
All these are equivalent so choose whatever makes the condition more clear (actually, consider storing it in a separate variable which you give a descriptive name).

How do you findIndex with conditionals like &&

Let's say you have a List l_mur = new List();
And you populate the list.
Then based on conditions you want to REMOVE some values without requerying...
l_mur.RemoveAt(l_mur.FindIndex(f => (f.xid == tmur.xid && f.sid == tmur.sid && f.mid == tmur.mid && f.bid == tmur.bid)));
However, the code I used here, does not seem to work. It tells me index out of range, but how can it be out of range if I am just searching for something that truly does exist.
List<T>.FindIndex() returns -1 in case there is no match found - which is out of range for List<T>.RemoveAt().
Also note that FindIndex() only returns the index of the first occurrence based on your predicate - if there is more than one match you will only be able to delete the first one of them with your current approach.
A better approach to delete in place based on a predicate would be RemoveAll():
l_mur.RemoveAll(f => (f.xid == tmur.xid && f.sid == tmur.sid && f.mid == tmur.mid && f.bid == tmur.bid));
May be a good idea is to filter the list to a new instance of the list:
var l_mur = l_mur.Where(f => (f.xid != tmur.xid || f.sid != tmur.sid || f.mid != tmur.mid || f.bid != tmur.bid));
Use this code:
l_mur.Remove(l_mur.Find(f => (f.xid == tmur.xid && f.sid == tmur.sid && f.mid == tmur.mid && f.bid == tmur.bid)));

how to combine textbox values in a linq query?

I have a page in which I have several textboxes in order to search depending the value of the textboxes,If I make the search eith only one value everithing works fine but if I try to combine 2 or more values I only get the result of the last textbox.
Here's my query hope you could help me.
var query = from m in SolContext.Menores
where ((m.Solicitud.fiIdSolicitud == rdTxtFolio.Value) || (m.Solicitud.fiAnioSolicitud == rdTxtAnioFolio.Value)
|| (m.Solicitud.CTEdoSolicitud.fcDescEdoSol == status) || (m.Solicitud.fiCircuito == cto) || (m.Solicitud.fiCiudad == cd)
|| (m.Solicitud.fcCveAdsc == adsc) || (m.Solicitud.fiExpEmpleado == rdTxtExp.Value) || (m.Solicitud.fcNomEmpleado == rdTxtNom.Text)
|| (m.Solicitud.fcPatEmpleado == rdTxtAPat.Text) || (m.Solicitud.fcMatEmpleado == rdTxtAMat.Text) || (m.fcPatMenor == rdTxtAPatMenor.Text)
|| (m.fcMatMenor == rdTxtAmatMenor.Text) || (m.fcNomMenor == rdTxtNomMenor.Text) || (m.fiSexoMenor == sexo) || (m.fiAnosMenor == rdTxtAniosMenor.Value) || (m.fiMesesMenor == rdTxtMesMenor.Value))
select m;
rgSolic.DataSource = query;
rgSolic.Rebind();
My guess is that the result of the first textbox is included in the result of the second one.
My guess is that you're using or. The first textbox that matches your value will end your search. If you want to check if it matches all your values, use and.
If that doesn't solve it, we'll need more info.

Categories