I want to get a subset of enums from an enum, to later select a random enum element based on the values of a Dictionary. I tried doing this:
var allEnums = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>();
var availableEnums = allEnums.Where(e => SomeClass.SomeDictionary[e] < someThreshold);
//Note: SomeDictionary<MyEnum, int>
Also, this does not work either:
var availableEnums = SomeClass.SomeDictionary.Where(entry => entry.Value < someThreshold);
The value of availableEnums is always {System.Linq.Enumerable+c__Iterator1D`1[[AircraftModel, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]}. I must be doing something very stupid, but how do I get this correct?
You'd want to use
var availableEnums = SomeClass.SomeDictionary
.Where(entry => entry.Value < someThreshold)
.ToList();
// or
var availableEnums = SomeClass.SomeDictionary
.Where(entry => entry.Value < someThreshold)
.ToArray()
FindAll was before the Linq extensions and projects results immediately, whereas Where is deferred, which allows you to efficiently chain multiple operations like OrderBy, Take and so on before projecting your results.
Related
The code below userModel.Carriers is the type of IEnumerable<CarrierModel>.
userModel.Carriers has a list of carriers having Ids. With those Ids, I want to get CarrierDivision usign linq. But, I can't get it right because linq sqlexpression is not compatible with IEnumerable expression.
userModel.Carriers = carriersForRegion.Select(carrier => Mapper.Map<CarrierModel>(carrier))
.ToList();
var carrierDivision = from c in db.CarrierDivision where c.Contains();
collection.Contains will generate .. WHERE CarrierId IN (1, 2, 3) sql query
var carrierIds = userModel.Carriers.Select(carrier => carrier.Id).ToArray();
var divisions = db.CarrierDivision
.Where(division => carrierIds.Contains(division.CarrierId))
.ToArray();
In case db.CarrierDivision returns IEnumerable(not database), then I would suggest to create HashSet of carrier ids.
var carrierIds = userModel.Carriers.Select(carrier => carrier.Id).ToHashSet();
var divisions = db.CarrierDivision
.Where(division => carrierIds.Contains(division.CarrierId))
.ToArray();
With HashSet search executed without extra enumerations - O(1)
I'd like to know it is it possible to create programmatically single LINQ query (for EntityFramework 6) with N .Where() clauses, but with OR between these .Where() clauses.
Imagine IQueryable object defined like:
var query = dbContext.MyTable.Where(mt => mt.TimeStamp >= DateBegin);
What I need else is add N (unknown number) of Where clauses, but with OR condition between them.
Image list of some object:
List<MyObject> myObj =
new List<MyObject>({new MyObject {val = "a" }, new MyObject { val = "b"}}); //In real code there is more than 1 property.
then I'd like to add Where() clauses to query like:
myObj.ForEach(mo =>{
// THIS CREATES -AND- BETWEEN WHERE CLAUSES, BUT I NEED -OR-
query.Where(q=>q.MyValue == mo.val); // In real code there is more than 1 property to compare
});
I was thinking about .Union() beteween queries, but It could generate union between separated queries and it's not optimal I think.
Thanks!
Here's the solution: linq-to-entities-combining-predicates
Or course is necessary to use "latest" answer:
Copy/Paste class ParameterRebinder
Copy/Paste static class Utility
Usage:
Expression<Func<Car, bool>> theCarIsRed = c => c.Color == "Red";
Expression<Func<Car, bool>> theCarIsCheap = c => c.Price < 10.0;
Expression<Func<Car, bool>> theCarIsRedOrCheap = theCarIsRed.Or(theCarIsCheap);
var query = carQuery.Where(theCarIsRedOrCheap);
Because in my solution is N of expressions, I take first expression and then append other expressions in ForEach cycle.
var firstExpression = expressionList.First();
expressionList.Skip(1).ToList().ForEach(ex => { firstExpression = firstExpression.Or(ex); });
The beginning of my Linq query is below.
Pay attention only to the where clause. Does Linq do the ToLower() only once? Or does it do ToLower() for every element of searchWords?
var products = from d in xElem.Descendants(fileName)
where searchWords.All(t => d.Element(productName).Value.ToLower().Contains(t))
Assuming this is LINQ to Objects, it will absolutely do it (and indeed the Element call) on each element of searchWords. There's nowhere it could really store state to do anything else, implicitly. You can optimize this easily yourself though:
var products = from d in xElem.Descendants(fileName)
let lowerD = d.Element(productName).Value.ToLower()
where searchWords.All(t => lowerD.Contains(t))
Or in a non-query expression you could use a statement lambda:
var products = xElem.Descendants(fileName)
.Where(d => {
string lowerD = d.Element(productName).Value.ToLower();
return searchWords.All(t => lowerD.Contains(t));
})
... // rest of query
Note that there are other ways of performing case-insensitive comparisons which are more robust. For example:
var products = from d in xElem.Descendants(fileName)
let v = d.Element(productName).Value
where searchWords.All(t =>
v.IndexOf(t, StringComparison.CurrentCultureIgnoreCase) != -1)
The goal is to return a list of PARENT entities, based on attributes of their CHILD ENTITIES
eg Find me all the CASTLES where LADIES_IN_WAITING belong to PRINCESS 'X'
I want to do something like this:
var query = ObjectSet.Include(c => c.LADIES_IN_WAITING);
query = query.Where(p => p.REGION.ToLower().Contains("shrekVille"));
query = query.Where(p => p.LADIES_IN_WAITING.Where(c => c.PRINCESS.Equals("fiona")));
var results = query.ToList();
This is obviously the incorrect syntax but i can't find any clear examples of how to structure the Query.
I am currently resorting to something like this:
var query = ObjectSet.Include(c => c.LADIES_IN_WAITING);
query = query.Where(p => p.REGION.ToLower().Contains("shrekVille"));
// Get the results from the DB using the query built thus far
var results = query.ToList();
// Now filter the list in memory manually
foreach (var castle in results)
{
var matchingParents = new List<CASTLE>();
var matchingChildren = castle.LADIES_IN_WAITING.Where(a => a.PRINCESS.Equals("fiona"));
if (matchingChildren.Count() > 0)
matchingParents.Add(matchingChild);
}
results = matchingParents;
Any suggestions on how to correctly build the Query would be most welcomed!
You probably want to use the Any operator. It returns true if one item in a collection (i.e. 'any' of them) satisfies the predicate.
var query = ObjectSet.Include(c => c.LADIES_IN_WAITING);
query = query.Where(p => p.REGION.ToLower().Contains("shrekVille"));
// filter the query where, for each p,
// any of the LADIES_IN_WAITING have PRINCESS.Equals("fiona") == true
query = query.Where(p => p.LADIES_IN_WAITING.Any(c =>
c.PRINCESS.Equals("fiona"))); var results = query.ToList();
The complementary operator is All, which would filter your query to those results that have all the LADIES_IN_WAITING meeting the PRINCESS.Equals("fiona") criteria.
I've got a list of IQueryable. I'm trying to split this list into an array of IQueryable matching on a certain field (say fieldnum) in the first list...
for example, if fieldnum == 1, it should go into array[1]. I'm using Where() to filter based on this field, it looks something like this:
var allItems = FillListofMyObjects();
var Filtered = new List<IQueryable<myObject>(MAX+1);
for (var i = 1; i <= MAX; i++)
{
var sublist = allItems.Where(e => e.fieldnum == i);
if (sublist.Count() == 0) continue;
Filtered[i] = sublist;
}
however, I'm getting the error Field "t1.fieldnum" is not a reference field on the if line. stepping through the debugger shows the error actually occurs on the line before (the Where() method) but either way, I don't know what I'm doing wrong.
I'm farily new to LINQ so if I'm doing this all wrong please let me know, thanks!
Why don't you just use ToLookup?
var allItemsPerFieldNum = allItems.ToLookup(e => e.fieldnum);
Do you need to reevaluate the expression every time you get the values?
Why not use a dictionary?
var dictionary = allItems.ToDictionar(y => y.fieldnum);