To find if a list contains a specific string - c#

I have a list of a model called results. I need to get those values from the results list which contain this particular string.
List<Search> results = new List<Search>();
results = db.Users.Select(f => new Search{ Name = f.Name, Type = f.OrganizationType.Name, County = f.County.Name }).ToList();
results = results.Where(w => (model.Name == null || w.Name.Contains(model.Name))).ToList();
While the first result query returns 5000 rows, the second one returns 0. What i am trying to do in the second query is if the Name is null or if the Name contains part of a string, add it to the results list.
Am I missing something?
I did check a couple of links which basically asked me to do the same like Check if a string within a list contains a specific string with Linq
I have checked the value for model.Name and it shows up properly. Also the query works if there is no search string that is when Model.Name = null, I get all the records

Consider this statement: Name is null or if the Name contains part of a string I hope you need to check an item in db.Users for null and Contains. One more thing I have to add here is- if x.Name is null then the following .Contains will raise NullReferanceException So you have to consider that as well. Now take a look into the following query:
List<Search> results = db.Users.Where(x=> x.Name==null || (x.Name !=null && x.Name.Contains(model.Name)))
.Select(f => new Search{ Name = f.Name, Type = f.OrganizationType.Name, County = f.County.Name }).ToList();

Related

How to return null in a GroupBy statement when one of the values in the non-key column contains null?

I want to group a table consisting of 3 columns: Country, Person Name and Grade.
My goal is: when grouping countries that have one or more people with NULL grades, the final output of the GroupBy LINQ statement should be NULL for that specific country, regardless of other people's grades in that country.
However, when I write the below code to group it, LINQ assumes that the NULLs are equal to zeros and returns the sum total of the grades for the specific country.
var query = toIEnumerable.GroupBy(c => c.country).Select(r => new
{
r.Key,
sumGrade = r.Sum(f => f.grade)
});
You can accomplish this using LINQ's Any method:
var query = toIEnumerable.GroupBy(c => c.country).Select(r =>
{
bool someWithNoGrades = r.Any(i => i.grade == null);
return new
{
r.Key,
sumGrade = !someWithNoGrades ? r.Sum(f => f.grade) : null
};
});

Where clause using Linq - search for a list of Object

One doctor can work in One hospitals.
The Doctor table looks like this:
Id
Name
Speciality
HospitalName
HospitalName is a string.
Hospital Table contains the following
Id
HospName
Address
Now, I have a List of Hospital Objects. Where I need to filter it using a List of Doctor. I need to search from the Doctors table, where the HospitalName is equal to HospName in the Hospital table.
Code:
List<Hospital> hos = listHospitals;
var doctors = docList
.Where(h=> listHospitals.Contains(h.HospitalName));
I get an error that states :
Can not convert form string to Hospital`
How can I solve this ?
You can use Any() like below.listHospitals is of type List<Hospital> and thus you will have to query that list to compare hospital name.
List<Hospital> hos = listHospitals;
var doctors = docList
.Where(h=> listHospitals.Any(x => x.HospitalName == h.HospitalName)).ToList();
Try this...
var list = docList.Where(d => listHospitals.FirstOrDefault(h => d.HospitalName == h.HospName) != null).ToList();
I'd say to use Count() instead of Any() since a List has a .Length or .Count property thus not need to go through the GetEnumerator()/MoveNext()/Dispose() sequence required by Any().
Resulting in the following code:
List<Hospital> hos = listHospitals;
var doctors = docList
.Where(h=> hos.Count(x => x.HospitalName == h.HospitalName) > 0).ToList();

What is the best way to write a two column query in LINQ to Entity 6? And save the results to two different variables?

How would you write "SELECT col.a, col.b FROM TABLE WHERE ID = 1" in LINQ to Entity 6 so that you could save col.a into variable A and col.b into variable B. You can do this with SqlReader by retrieving the index or column name, but with LINQ to Entity it is returned as one object. When returning a two field LINQ query to a list, both field are saved to the first index of the list and can only be accessed as the same list element. Is it standard to create two LINQ queries, one for each variable? Or am I missing part of the process?
Current query:
var result = (from col in cxt.Table
where col.ID == "1"
select new {col.a, col.b}).ToList();
If you are expecting exactly one record to return from database then what you can do:
var result = cxt.Table.FirstOrDefault(x => x.ID == "1");
//Notice that might be null if has not result
var a = result.a;
var b = result.b;
Will look very similar in query syntax but I think this method syntax neater in this case
I am not sure what exactly you are looking for. But selecting two variable by Linq is not so hard.
var value = (from ta in db.YourTable
where ta.ID = id
select new {
A = ta.a,
B = ta.b
}).FirstOrDefault();
var a = value.A;
var b = value.B;
If you use ToList() instead of FirstOrDefault(), you will get a list contain zero or more objects. You can simply use a loop to get field from each object.
forach(var value in values)
{
var a = value.A;
var b = value.B;
}

Getting records in between two records using Linq

I have a list of objects and need to get the list of records from this list. like I have of Countries and I need to get the list of countries which are in between country with name "Australia" and country "Indonasia", the list will not be sorted.
Am using c#.
I tried to use something like, get the index of first and second and then use that to get the list with a for loop, but would be handy if it can be done in single query.
If you do the following:
var elementsBetween = allElements
.SkipWhile(c => c.Name != "Australia")
.Skip(1) // otherwise we'd get Australia too
.TakeWhile(c => c.Name != "Indonasia");
you'll get the result you want without iterating through the list 3 times.
(This is assuming your countries are e.g. Country items with a Name string property.)
Note that this doesn't sort the countries at all - it's unclear from your question whether you want this or not but it's trivial to add an OrderBy before the SkipWhile.
this should do the job
var query = data.SkipWhile(x => x != "Australia").TakeWhile(x => x != "Indonesia")

find property value from List<Postavke>() with linq

I have class "Postavke" and then i store it into
List<Postavke> postavke = new List<Postavke>();
Now i want to find some elemnt (property) from this List. I know "Name", "Surname" and i want to get "Address".
How to get "Adress" if i know "Name" and "Surname". All this are properties in "Postavke" class
whole class
public class Postavke
{
#region Properties
public string Name { get; set; }
public string Surname { get; set; }
public string Address { get; set; }
#endregion
#region Methods
public Postavke(string name, string surname, string address, string oznakaLokacije, string oznakaZapore)
{
Name = ean;
Surname = surname;
Address = address;
}
#endregion
}
You can query postavke for all results that contain the name and surname and put the results into a list. Putting the results into a list I find makes things easier to validate and handle unforseen items as from the looks of it it is possible that duplicate items could appear.
if the results must have all data within the list item then:
List<Postavke> results = new List<Postavke>();
var query1 = from a in postavke
where a.Name == searchName
&& a.Surname == searchSurname
select a;
results.AddRange(query1);
this list will have all the results that contain the exact name and surname.
If you just want the address then you can use:
List<string> results = new List<string>();
var query1 = from a in postavke
where a.Name == searchName
&& a.Surname == searchSurname
select a.Address;
results.AddRange(query1);
this will produce a list of addresses. From here you can then validate the list if you want by doing such things as checking to see how many items in the list there are so you know how you want to handle it etc.
If you want to use just either the name or the surname then you can remove the line that asks for one or the other.
If you end up with duplicates but the results are the same then you can change the line
results.AddRange(query1);
to
results.AddRange(query1.Distinct());
by using the Distinct() method it will sort the query and remove duplicates so the list will not be in the same order as it would if you didn't use it.
If you only wanted one result then it's worth validating it by checking how many items are in the list by using
results.Count
you could if it equals 1 carry on, otherwise throw up a message or some other way you may want to handle it. Other pieces of validation that are good is to set values ToLower() and Trim() during the search as to avoid actually changing the original text.
So taking the last query as an example:
List<string> results = new List<string>();
var query1 = from a in postavke
where a.Name.ToLower().Trim() == searchName.ToLower().Trim()
&& a.Surname.ToLower().Trim() == searchSurname.ToLower().Trim()
select a.Address;
results.AddRange(query1);
you can also filter the query with the where clause after you make the query by doing:
List<string> results = new List<string>();
var query1 = from a in postavke
select a.Address;
query1 = query1.Where(h => h.Name == searchName);
query1 = query1.Where(h => h.Surname == searchSurname);
results.AddRange(query1);
The 2 where clauses were split to show you can perform where clause at different points so you could have where clauses within if statements. you can combine the 2 into:
query1 = query1.Where(h => h.Name == searchName && h.Surname == searchSurname);
Hopefully this helps
This will work if you can be sure there's exactly one match
var address = poatavke.Where(p=>p.Name == name && p.Surname == surname).Single().Address;
If you don't know if there's no matches or exactly one you can do:
var posta = poatavke.Where(p=>p.Name == name && p.Surname == surname).SingleOrDefault()
var address = posta == null ? string.Empty : posta.Address;
if you don't know how many matches there's going to be but always want the first (or are using ET which doesn't understand Single())
var posta = poatavke.Where(p=>p.Name == name && p.Surname == surname).FirstOrDefault()
var address = posta == null ? string.Empty : posta.Address;

Categories

Resources