FirstOrDefault behavior directly in LINQ statement - linq

Seems like I may have missed something simple in the syntax, but I'd like to get the results of FirstOrDefault from a linq statement directly without having to store the IEnumerable in a temporary variable first. Something like this:
var bestCar = from c in cars
orderby c.Price
select first c
I know the first keyword doesn't actually exist but illustrates what I'd like to do. I also know I can wrap the from...select statement in parenthesis and call FirstOrDefault directly but I think the above syntax is cleaner and easier to read.

Enumerable.FirstOrDefault is one of the extension methods in the Enumerable class which does not have a corresponding LINQ syntax element. The only way to bind to this method is via method call syntax.
You can avoid the temporary by doing the follownig
var bestCar = (from c in cars
orderby c.Price
select c).FirstOrDefault();

There isn't a way to do that. LINQ is used for defining a query. Doing that doesn't actually cause an evaluation, whereas executing FirstOrDefault (or enumerating over it) executes the query.

var bestCar = (from c in cars
orderby c.Price
select c).FirstOrDefault()
OR
var bestCar = cars.OrderBy(c => c.Price).FirstOrDefault()

var bestCar = (from c in cars
orderby c.Price
select c).FirstOrDefault();
Sorry I didn't read your question entirely, it seems that this may be exactly what you don't want to do.

In VB you can use 'Aggregate':
Dim BestCar = Aggregate c In cars
Order By c.Price
Into FirstOrDefault

Related

Composable LINQ Select Clause

Is there a way to build on to the select clause of a previously defined LINQ query?
For example:
var stuffQuery =
from stuff in MyStuff
select new {
stuff.Name
};
var query2 =
from stuff in stuffQuery
join otherStuff in YourStuff on stuff.Name equals otherStuff.Name
select new {
stuff.*, // how can I accomplish this?
YourStuff = new {
otherStuff.PropertyX
}
};
The result I want is an object like:
string Name
anonymous YourStuff
string PropertyX
I thought about using a "Combine" method which would reflectively combine my two anonymous objects into a dynamic. But Linq-to-Sql won't know what to do with the method.
Instead, I think I need a method which returns the select expression. Its parameters would be the first Queryable, and the select expression for the second Queryable. Something like:
var query2 =
from stuff in stuffQuery
join otherStuff in YourStuff on stuff.Name equals otherStuff.Name
GetCombinedSelectClause(stuffQuery, new {
YourStuff = new {
otherStuff.PropertyX
}
});
How can I accomplish this? I'm not married to any particular syntax-style. However, I'd prefer not to use a string-based solution (such as System.Linq.Dynamic).
How about ExpandoObject? I believe it can do exactly what you need.
My question probably isn't worded the best it could be. However, I do not think LINQ queries were designed to accomplish the goal I was after.
I'm closing the question because I simply do not think the answer is achievable.

Problems getting System.Linq.Dynamic to work.

I have included the System.Linq.Dynamic library in my project via Nuget. The following is my linq query which works fine if I use typed fields to be returned in the select. But using System.Linq.Dynamic I should be able to use a string value for the select. I've followed the examples that I found but all I get back from the select is the string itself.
What am I missing?
var predicate = PredicateBuilder.False<Name>();
predicate = predicate.And(d => d.ID == "100053");
var results = from n in Names
.AsExpandable()
.Where(n=> n.ID=="100053")
join d in InstitutionDemographics on n.ID equals d.ID
join m in MemberAdhocIds on n.ID equals m.ID
join a in NameAddresses on n.BillingAddressNumber equals a.AddressNumber
join mas in MemberAdhocServices on n.ID equals mas.InstitutionID
select("new(n.ID,n.Company,n.MemberStatus,n.Email,n.MemberType,n.USCongress,n.FAX,n.County,d.NumberYearsAMember,d.Population,d.FederalReserveDistrict,d.FDICCertificateNumber,d.FRSID,d.ICBADistrictCode,d.UD_Minority_Type,d.MSA,d.NumberOfBranches,d.PubliclyTraded,d.SRAMemberships,d.Assets,d.RSU,d.FutureDues,d.InstitutionType,d.AgLoanPercentageTotal,m.CCRP,a.City,a.State,a.Address1,a.ZIP)");
results.Dump();
If you're telling the select statement to select a string, it's not going to return the values for those strings. What happens if you try without the quotes?
I'm not fluent in C#, being a VB fiend, but you could try something like:
Select New With {.Id = n.ID, .Company = n.Company, ...etc}
Does that make sense? Apologies if I've misunderstood your question.
My mistake. I didn't realize how the extension worked. I was expecting the extension to work in query syntax when in reality it would only work in method syntax.
i.e.
.Select("new (ID,Name)");
(this works)
-vs-
select(new(ID,Name)");
(this doesn't work)

How join in linq to nhibernate

I have a linq query in Nhibernate.
var q = SessionInstance.Query<Person>();
if (!String.IsNullOrEmpty(dto.FirstName))
q = q.Where(x => x.FirstName.Contains(dto.FirstName));
This query is for Search in persons list. I need to add a join between Person and Employee classes. for add a where condition on a property in Employee class.
For example it :
if (dto.Type == PersonEnumType.EmployeeType)
q = q.Where(employee => employee.Code.Contains(dto.Code));
How can I add something like it?
My sql query is similar this :
select * from Person_Table
left outer join Employee_Table on Person_Table.Id = Employee_Table.Person_id_fk
where Person_Table.FirstName like '%Phill%' and Employee_Table.Code like '332'
It's hard to tell how to do this without knowing your mappings, but it could be something like this:
q.Where(x => x.FirstName.Contains(dto.FirstName))
.Where(x => x.Employees.Any(emp => emp.Code.Contains(dto.Code)))
If there is a Person.Employees at all. But I must admit I don't know if Linq to NHibernate supports Any(). That probably depends on which vesion of L2N you use.
If this does not work you should try your luck with GroupJoin() (because of the outer join), but I'm even more insecure about solid L2N support for that one. As far as I can see it is in L2N since 3.0 beta, but whether it is reliable...?

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.

Like condition in LINQ

I am relatively new to LINQ and don't know how to do a Like condition. I have an IEnumerable list of myObject and want to do something like myObject.Description like 'Help%'. How can I accomplish this? Thanks
Look here:
http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/10/16/linq-to-sql-like-operator.aspx
Snippet:
StartsWith and Contains:
var query = from c in ctx.Customers
where c.City.StartsWith("L") && c.City.Contains("n")
select c;
And if you should use it with LINQ to SQL (does not work with LINQ to Objects):
Custom LIKE (System.Data.Linq.SqlClient.SqlMethods.Like):
var query = from c in ctx.Customers
where SqlMethods.Like(c.City, "L_n%")
select c;
You generally use the exact same syntax you'd use outside a query.
myObject.Description.StartsWith("Help")
Whether this actually works depends on where you're using LINQ (it might either be ran as code, in which case everything works, or get converted to something like else, such as SQL, which might have limitations), though, but it's always worth a try.
You can use StartsWith, EndsWith, or Contains depending where you want to check:
var result = from o in myCollection
where o.Description.StartsWith("Help")
select o;
You can optionally pass a StringComparison to specify whether to ignore case or not (for StartsWith and EndsWith) which would make the operation behave more like a SQL query:
var result =
from o in myCollection
where o.Description
.StartsWith("Help", StringComparison.InvariantCultureIgnoreCase))
select o;
If you want to do a case insensitive contains, you need to use IndexOf instead:
var result =
from o in myCollection
where o.Description
.IndexOf("Help", StringComparison.InvariantCultureIgnoreCase) > 0
select o;
you can use string.StartsWith or string.EndsWith or string.Contains property of string to use it as Like Operator.
Startswith will work for Like 'A%'
Endswith will work for Like '%A'
Contains will work like '%A%'

Resources