Get min DateTime from Linq - linq

How can I convert this linq query to single line?
var closets = (from v in options
select v.ExceriseDate).Min();
var option = options.Where(v => v.ExceriseDate == closets).Single();
return option;

Like so:
options.OrderBy(v => v.ExceriseDate).First();
I'll also add that you don't want to use Single() unless you can guarantee it will be unique. It will throw an exception if more than one exist. That would happen if two if your objects shared the same ExceriseDate. Lastly if you prefer the query syntax for Linq over the expression method:
var option = (from v in options
orderby v.ExceriseDate
select v).First();

Related

How to add a second where clause to a linq expression

Trying to add a second where clause to a linq expression but it won't register.
var query = _dbSetBookedResource.AsQueryable<Resource>();
var resources = (from Resource in query where Resource.DateFrom == date select Resource)
if(true)
{
resources.Where(b => b.MemberId == currentUserId);
}
For some reason the second where clause won't register.
For some reason the second where clause won't register.
That's because you're not using the return value anywhere. That's just setting up a query, but then ignoring it. No LINQ methods change the value they're called on - instead they create a new query which has the appropriate filtering, projection etc.
You need:
resources = resources.Where(b => b.MemberId == currentUserId);
Also note that your initial query could be written more simply as:
var resources = query.Where(r => r.DateFrom == date);
Query expressions are overkill when all you want is a simple filter or projection.

Convert string value to entity in linq where query

I am using jqgrid in MVC 4. I have written a method for getting a list in linq.
In my function I am getting all values of jqgrid with search criteria i.e. Operator AND/OR
, operations Equals to, not equals to etc. Here I am also getting the column name like Name, City, State etc.
My problem is I can't pass the column name directly in linq query i.e. I have to use the column name as x => x.Name
switch (rule.field)
{
case "Name":
query = query.Where(x => x.Name.StartsWith(rule.data, StringComparison.OrdinalIgnoreCase));
break;
case "Course":
query = query.Where(x => x.Course.StartsWith(rule.data, StringComparison.OrdinalIgnoreCase));
break;
}
In rule.field I am getting column Name i.e. Name, city, state etc. I want to pass the column name which I am getting in rule.filed in LINQ query instead of x =>x.Name.
Is there any way to do it so I can avoid writing switch cases?
You can use System.Linq.Dynamic, which can be installed as a Nuget package along with string.Format. The syntax would then look something like..
var newquery = query.AsQueryable()
.Where(
string.Format("{0}.ToUpper().StartsWith(#0)", rule.field)
,rule.data.ToUpper());
You could always use reflection:
query = query.ToList().Where(p => {
var field = p.GetType().GetProperty(rule.field);
var value = (String) field.GetValue(p);
return value.StartsWith(rule.data, StringComparison.OrdinalIgnoreCase);
});
Warning: Reflection is slow. Only use this for short lists. Since you're dealing with UI rendering, I'm assuming this won't be a problem.
edit: My example is assuming all properties are indeed properties (and not fields), and that all properties are Strings. You may need to alter the code for your specific case.

Return Linq query results into List object

I am trying to return the results of a query into a List object, however the following code, as I normally use, does not work. Still relatively new to Linq, can someone explain the correct syntax/what's going on? This will work if I change the data type of productTraining to var...
List<AgentProductTraining> productTraining = new List<AgentProductTraining>();
productTraining = from records in db.CourseToProduct
where records.CourseCode == course.CourseCode
select records;
Select() and Where() will return IQueryable<T>, not List<T>. You've got to convert it to a List<T> - which actually executes the query (instead of just preparing it).
You just need to call ToList() at the end of the query. For example:
// There's no need to declare the variable separately...
List<AgentProductTraining> productTraining = (from records in db.CourseToProduct
where records.CourseCode == course.CourseCode
select records).ToList();
Personally I wouldn't use a query expression though, when all you're doing is a single Where clause:
// Changed to var just for convenience - the type is still List<AgentProductTraining>
var productTraining = db.CourseToProduct
.Where(records => records.CourseCode == course.CourseCode)
.ToList();

Var vs IEnumerable when it comes to Entity Framework

If I were to use IEnumerable instead of var in the code example below, will the SQL be generated only during the execution of the foreach statement? Or will it execute as an when the Linq statements are evaluated?
var query = db.Customers.Where (c => c.Age > 18);
query = query.Where (c => c.State == "CO");
var result = query.Select (c => c.Name);
foreach (string name in result) // Only now is the query executed!
Console.WriteLine (name);
Another example:
IEnumerable<Order> query = db.Orders.Where(o => o.Amount > 1000);
int orderCount = query.Count();
Would it be better to use var (or IQueryable) as it would be executed a select count(*)... when .Count() is executed or would it be exactly same with the IEnumerable code shown above?
It would make no difference. var is just syntactic sugar. If you hover over var, you will see what type C# thinks your query is.
From http://msdn.microsoft.com/en-us/library/bb383973.aspx
Beginning in Visual C# 3.0, variables that are declared at method scope can have an implicit type var. An implicitly typed local variable is strongly typed just as if you had declared the type yourself, but the compiler determines the type. The following two declarations of i are functionally equivalent:
var i = 10; // implicitly typed
int i = 10; //explicitly typed
If you want to perform actions on your query that SQL wouldn't know what to do with, such as a method defined in your class, then you could use AsEnumerable().
For example:
var query = db.Customers
.Where(c => c.Age > 18)
.AsEnumerable()
.Select(c => GetCustomerViewModel());
//put definition of GetCustomerViewModel() somewhere in the same class
Update
As Omar mentioned, if you want your query to be executed immediately (rather than deferred), use ToList(). This will immediately enumerate the IQueryable/IEnumerable and fill the list with the actual data from the database.
In general, the SQL is generated when GetEnumerator is called on the IQueryable.
In your example, there is a subtle difference that you may want to consider. Let's take your original example:
var query = db.Customers.Where (c => c.Age > 18);
query = query.Where (c => c.State == "CO");
var result = query.Select (c => c.Name);
In this case if you change your first query to IEnumerable query = ..., then the second line would use the IEnumerable version of the Where extension (LINQ to Objects) rather than the IQueryable one (LINQ to SQL/EF). As a result, when we start iterating, the first where clause is passed to the database, but the second where clause is performed on the client side (because it has already been converted to an IEnumerable).
Another subtle item you want to be aware of is the following type of code:
var query = db.OrderBy(c => c.State);
query = query.Customers.Where(c => c.Age > 18); // Fails: Widening
In this case, since your original query returns IOrderedQueryable rather than IQueryable. If you try to then assign query to the result of the .Where operation, you're trying to widen the scope of the return type and the compiler will refuse to perform that widening. As a result, you have to explicitly specify the baseline type rather than using var:
IQueryable<Customer> query = db.OrderBy(c => c.State); // Is narrowing rather than widening.
query = query.Customers.Where(c => c.Age > 18);
Linq queries return IQueryable<> or IEnumerable<>, the execution of both is deferred.
As DanM stated, whether or not you use var or IEnumerable<> it all depends on the return value of the method you're calling: if it's an IEnumerable<> or IQuerable<> it'll be deferred, if you use .ToList(), it'll be executed right away.
When to use var comes down to personal choice/style. I generally use var when the return value is understood from the line of code and variable name or if I'm instantiating a generic with a long declartion, e.g. Dictionary<string, Func<Order, object>>.
From your code, it's clear that a collection of Customers/Orders is returned, so I would use the var keyword. Again, this is a matter of personal preference.

Nhibernate linq. The where extension method does not add the where clause to the SQL command, why?

I want to add the where clause to a linq statement, but it doesn't behave as i would expected it to.
When i use this code:
IQueryable<Employee> EmpQuery = from e in Session.Query<Employee>() where e.Surname == "Test" select e;
EmpQuery.ToList();
or i use this code:
IQueryable<Employee> EmpQuery = (from e in Session.Query<Employee>() select e).Where(e => e.Surname == "Test");
EmpQuery.ToList();
The where clause is included in the SQL command, but when i try it this way:
IQueryable<Employee> EmpQuery = from e in Session.Query<Employee>() select e;
EmpQuery.Where(e => e.Surname == "Test");
The where clause is not included in the SQL command. Why is this? Is there another way to dynamically add criteria to a Nhibernate Linq query?
You're not using the return value of Where. LINQ is designed around functional concepts - calling Where doesn't modify the existing query, it returns a new query which applies the filter. The existing query remains as it was - which means you can reuse it for (say) a different filter.
Note that your current query expression (from x in y select x, effectively) is pretty pointless. I would suggest simply writing:
var query = Session.Query<Employee>().Where(e => e.Surname == "Test");
Just to clarify on Jon's remark, your implementation would be fine with the following tweak:
IQueryable<Employee> modifiedQuery = EmpQuery.Where(e => e.Surname == "Test");
Then just invoke the appropriate enumerator (ToList, ToArray, foreach) on modifiedQuery. And I wouldn't say that it create a complete new query, but instead creates a query which wraps around the original (kind of along the lines of the adapter pattern). Granted, your example doesn't need the additions, but this is how you would add additional criteria onto an existing LINQ expression, and that is what your question actually asked.

Resources