I’m having issues creating an Where clause using C# and lambdas.
I have the following method GetRecommendedstudents(Guid studId)
The variable string filtersByRoles can hold a comma-delimited value such as: "xp,windows,windows8 or "xp,windows,windows8,windo " etc..
I then have the following C# lambda query:
I need get data from database by comparing 2 fields.
enter code here
var student= DataContext.students.Find(studId);
ex: var x = DataContext.students.Where(L => (L.job == student.studentJobLocation)).AsQueryable();
Next i want comapare student know os("xp,windows,windows8 )
ex: var y = x.students.Where(L => (s => (s.jobOperaitngsys.Split(',') == student.studentknowOS)), StringSplitOptions.RemoveEmptyEntries);
How to compare this to fields? jobOperaitngsys and studentknowOS
you should use contain. because split returns string array.
s.jobOperaitngsys.Split(',').Contains(student.studentknowOS)
Related
This question already has answers here:
Linq Select All Items Matching Array
(2 answers)
Linq filter List<string> where it contains a string value from another List<string>
(4 answers)
Closed 4 years ago.
How can I create LINQ expression to find elements from collection contains names from string array?
string[] names = ["John", "Hanna", "Bill", "Donald"];
I've created expression like below but it is not correct. How can I fix that?
result = (x => x.CompanyEmployeeName.Contains(names));
If you want check if names contains x.CompanyEmployeeName, you'll want to use:
result = something.Where(x => names.Contains(x.CompanyEmployeeName));
let myCollection be the collection of a custom class having a property Name. you have to get all objects from that collection based on the condition that object's name should be available in the names array. Then You can try this:
var filteredItems = myCollection.Where(x=> names.Any(y=>y == x.Name));
I have added a working example here
In your LINQ, you should have a collection first.
Ex: if you have a list: listCompanyEmployee then you can use bellow expression:
var result = listCompanyEmployee.Where(x => names.Contains(x.CompanyEmployeeName));
You need to reverse it. Check if the names contains the employee
var result = db.CompanyEmployee.Where(x => names.Contains(x.CompanyEmployeeName));
One other option, which is prefered if the list in context are larger then your sample data, is to use Join
var result = db.CompanyEmployee.Join(names, x=> x.CompanyEmployeeName, n => n, (x,n)=> n);
You can use Array.Exists. Example if you want to check if names contains CompanyEmployeeName:
result = something.Where(x => Array.Exists(names, name => name == x.CompanyEmployeeName));
and you can use Array.IndexOf like:
result = something.Where(x => Array.IndexOf(names, x.CompanyEmployeeName) != -1);
In my project, I need to return a list of car data that does not match the model Id' provided in the array. I'm unsure on how I would go in getting my query to work. So far i have the following below:
var IdList = new List<int> { 60,61,62, 63, 64, 65 };
var query = Context.ManufacturersTable.Where(m => m.Date == date && m.CountryToship = country && m.ExportOnly == false);
if(query.Count() > 0)
query = query.Where(x => x.CarMoreInfoTable.CarModelTable.Where(f => IdList.Contains(f.ModelId))) //Cannot convert lambda expression to intended delegate type error here
return query
As you can see in the above query I have 3 tables all linked to each other. But please could some direct me on how I would query all data that does not contain the Id's in the given array?
Thank you
You have an error because second 'Where' is the issue here, first Where expects to delegate method return bool instead of IEnumerable. (Comment edit) And I think you have to negate:
IdList.Contains(f.ModelId)
Edit
If you need Car Data (I will assume that it is inside CarModel class) then you need change first Where to SelectMany (we would like to merge many collections into one) and negate the inner expression (with contains).
var result = query
.SelectMany(x => x.CarMoreInfoTable.CarModelTable
.Where(f => !IdList.Contains(f.ModelId))).ToList();
I have a string like this:
RoleId,RoleName|CategoryId,CategoryName
I split them first like this:
string delm = "RoleId,RoleName|CategoryId,CategoryName";
string[] FieldsToReplace = attributes[0].IdsToReplaceWith.Split('|');
Suppose i have a variable in which i have RoleId:
string test = "RoleId";
Now what i am trying to get each the array item in which has string RoleId, i don't want to use contains i need exact match.
I have tried this query:
var test = FieldsToReplace
.Where(x=>FieldsToReplace
.All(y => y.Split(',').Equals(delm))).ToArray();
i can harcode like this for first index:
var IdProperty = FieldsToReplace.FirstOrDefault(x => x.Split(',')[0] == delm);
but i want it dynamic so it check each item of array which i got after , split.
but it returns no record.
Any help will be appreciated.
You want to split on your elements of the array. Besides that it seems appropriate to check if any element of these splitted ones are equal to your comparison string:
var test =
FieldsToReplace
.Where(x => x.Split(',')
.Any(y => y.Equals(prop.Name)))
.ToArray();
I try to filter my items according to unknown number of filters.
//item.statusId is nullable int
//statusIds is a string
{...
var statusIds = Convert.ToString(items["StatusId"]);//.Split(';');
results = mMaMDBEntities.MamConfigurations.Where(item =>
FilterByStatusId(statusIds, item.StatusId)).ToList();
}
return results;
}
private bool FilterByStatusId(string statusIds, int? statusId)
{
return statusIds.Contains(statusId.ToString());
}
But I get this error:
LINQ to Entities does not recognize the method 'Boolean FilterByStatusId(System.String, System.Nullable1[System.Int32])' method, and this method cannot be translated into a store expression.`
Any idea how to re-write it?
If statusIds is an array then you can do:
results = mMaMDBEntities.MamConfigurations
.Where(item => statusIds.Contain(item.StatusID)).ToList();
Some what similar to SQL Select * from table where ID in (1,2,3)
EDIT:
From your code it appears you have a string with semicolon separated values. You can try the following to get an array of int and later use that in your LINQ expression.
var str = Convert.ToString(items["StatusId"]);//.Split(';');
// string str = "1;2;3;4;5"; //similar to this.
int temp;
int[] statusIds = str.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries)
.Select(r => int.TryParse(r, out temp) ? temp : 0)
.ToArray();
then later you can use the int array in your expression like:
results = mMaMDBEntities.MamConfigurations
.Where(item => statusIds.Contain(item.StatusID)).ToList();
Why not insert the predicate statement directly into the where clause?
like this:
results = mMaMDBEntities.MamConfigurations.Where(item => statusIds.Contains(item.StatusId).ToList();
you might need to convert the string array resulting from the Split to a List or IEnumerable to make this work.
The exception is pretty self-explanatory, the method cannot be converted to a SQL statement in the form you wrote it, but if you write it like above, you should obtain the same result and it will work.
I'm trying to construct a Where clause for a Linq statement which needs to determine whether the AccountNumber values retrieved as below exist in a List<string> collection.
I've thus far tried this:
private void FindAccountNumbers(List<string> AccountNumbers)
{
var query = from abc
select new
{
AccountNumber = abc.AccountNumber
};
query = query.Where(AccountNumbers.Contains(x => x.AccountNumber));
}
However I get the following build error:
The type arguments for method
'System.Linq.Queryable.Where(System.Linq.IQueryable,
System.Linq.Expressions.Expression>)' cannot
be inferred from the usage. Try specifying the type arguments
explicitly.
At runtime, query contains AccountNumber values, and I'm trying to pare this down based on matches found in the AccountNumbers collection (similar to an IN statement in TSQL). Should I be using Intersect instead of Contains? What am I doing wrong??
I think you want to have this:
query = query.Where(x => AccountNumbers.Contains(x.AccountNumber));
This doesn't work?
var query = from x in abc
where AccountNumbers.Contains(x.AccountNumber)
select new { x.AccountNumber };
That would give you back any AccountNumber in that list, unless AccountNumber isn't actually a string. That could be your problem.
Its because your syntax for from is wrong, I'm guessing that your collection is abc of items to match against is abc
The correct syntax would be (Version 1)
var query = from x in abc
select new { AccountNumber = x.AccountNumber };
query = query.Where(x=>AccountNumbers.Contains(x.AccountNumber));
you don't need to do an anonymous type either as you are just wanting the same field you could just do (Version 2)
var query = from x in abc select x.AccountNumber;
query = query.Where(x=>AccountNumbers.Contains(x));
However you could just slap the Where straight onto your original collection. (Version 3)
var query = abc.Where(x=>AccountNumbers.Contains(x.AccountNumber);
Or if you are just trying to find whether any exist in the collection (Version 4)
var query = abc.Any(x=>AccountNumbers.Countains(x.AccountNumber);
Version 1 will return IEnumerable<string>
Version 2 will return IEnumerable<string>
Version 3 will return IEnumerable<type of the items in abc>
Version 4 will return bool
Let me verify what you're trying to do.
You have a collection of objects abc. You want to pull out the AccountNumber from each member of that collection, compare it to the list of account numbers passed in, and determine... what? If there IS any overlap, or WHAT the overlap is?
If the AccountNumber field is a string, you could do this:
private IEnumerable<string> OverlappingAccountNumbers(IEnumerable<string> accountNumbers)
{
return abc.Select(x => x.AccountNumber)
.Intersect(accountNumbers);
}
Or for the boolean case:
private bool AnyOverlappingAccountNumbers(IEnumerable<string> accountNumbers)
{
return abc.Select(x => x.AccountNumber)
.Intersect(accountNumbers)
.Count() > 0;
}
I'd go with this:
private void FindAccountNumbers(List<string> AccountNumbers)
{
// Get a strongly-typed list, instead of an anonymous typed one...
var query = (from a in abc select a.AccountNumber).AsEnumerable();
// Grab a quick intersect
var matched = query.Intersect(AccountNumbers)
}
One liner?
var query = (from a in abc select a.AccountNumber).AsEnumerable().Intersect(AccountNumbers);
The last answer are wrong because did mention one important point and obviously didn't be tested, the first issue is, you can't mix between an sql query than not been execute and a string's list, YOU CAN'T MIX!!! the solution for this problem and tested is:
var AccountNumbers = select accountNumber from table where.... // is a entitie
private void FindAccountNumbers(IQueryable<acounts> AccountNumbers) //entitie object not string
{
var query = from abc
select new
{
AccountNumber = abc.AccountNumber
};
query = query.Join(AccountNumbers, abc => abc.AccountNumber, aco=> aco, (ac, coNum) => cpac);
}
It really works! is necessary to mention this solution is when you are working with linq and entities framework!