Where with IN operator using Linq on NHibernate - c#

I have a linq query with NHibernate using Session.Query<T> method and I in this query I Fetch some complex properties and collection properties. I would like to know, how can I add an condition with IN operator from an int[]? Look my code:
public IEnumerable<Product> GetProducts(int[] idCategories)
{
// how to add IN condition here or a subquery
var query = Session.Query<Product>()
.Where(?????)
.Fetch(x=>x.Category)
.FetchMany(x=>x.Status).ThenFetch(x=>x.Item);
return query.ToList();
}
I have another method doing a query to get this int[] and I would like to apply it here, or if is there any way to add this subquery on the IN operator, I really appreciate!
OBS: I could convert int[] to List<int> if its necessary.
Edits
I got this int[] by a query like:
return session.Query<Category>.Where(...).Select(x => x.Id).ToArray();
My second question is, how could I add this query as a subquery to filter by category?
Thank you!

You don't really need the IN operator. You can just do it like this:
.Where(x => idCategories.Contains(x.Category))
Note: Contains is an extension method. You need to ensure that you have a using statement for System.Linq, but you probably already have it.

Take a look on Restrictions, for example
var query = Session.Query<Product>()
.Where(Restrictions.In(Projections.Property<Product>x=>x.Id),idCategories))
.Fetch(x=>x.Category)
.FetchMany(x=>x.Status).ThenFetch(x=>x.Item);

About sub query, you need Subqueries class
var query = Session.Query<Product>()
.Where(Subqueries.WhereProperty<Product>(x=>x.Id)...)
.Fetch(x=>x.Category)
.FetchMany(x=>x.Status).ThenFetch(x=>x.Item);
for more details please look here How to do subqueries in nhibernate?

Related

How to detect that one field of collection exist into another list with linq?

I try to detect that AirCoNam1 field exist into airlines list or no. I wrote this linq query but get error.
aFlightList is a collection that contain AirCoNam1 field.
How to fix this?
aFlightList=aFlightList.Any( airlines.Contains(x=>x.AirCoNam1)).ToArray();
You can use the Intersect Linq method
var doesContain = aFlightList.Intersect(airlines.Select(a => a.AirCoNam1)).Any();
The right way is this :
aFlightList=aFlightList.Where(x=>airlines.Contains(x.AirCoNam1)).ToArray();
Any() returns boolean. You can't call ToList() on a boolean value. It isn't clear from the question, but looks like you want to use Any() in a where clause, something like the following :
aFlightList = aFlightList.Where(f => airlines.Any(a => a == f.AirCoNam1))
.ToArray();

Convert LINQ method syntax with method withing .Select() to LINQ query syntax

I currently have the following code:
dataSource.Where(row => row.Value == 1)
.Select(row => {row["Text"] = translatedText; return row;})
.Single();
So my goal is to select the DataRow with "Value=1" and at the same time set the value in the "Text"-column to some other value (in my case a string-variable transalatedText).
This already works fine with the method chain mentioned above but I generally prefer the LINQ syntax. Is there a possibility to translate this method chain to LINQ?
My problem is that I do not know how to translate the function in the Select-method to LINQ-format. I dont want to create a new DataRow but want to really edit the selected one. (So I don't want to use from x in y where z select new DataRow(...) but to really edit my x if possible)
Thanks!
Is there a possibility to translate this method chain to LINQ?
(By "to LINQ" I believe you mean "to query expression syntax".)
Not directly, no. Effectively, you can only convert expression-bodied lambda expressions into query syntax. There's a good reason for that: LINQ is designed not to have side effects, whereas your "query" does have side-effects.
I would personally write your code like this instead:
var row = DataSource.Single(row => row.Value == 1);
row["Text"] = translatedText;
That neatly separates the querying from the side-effect. If you really, really want to use query expression syntax, you could write:
var query = (from row in DataSource
where row.Value == 1)
select HorribleMutatingMethod(row)).Single();
...
private DataRow HorribleMutatingMethod(DataRow row)
{
row["Text"] = translatedText;
return row;
}
... but please don't.

Add single item to linq to sql query

I would like to add a single item to the results of a linq query. I know it's not possible to join a local source and a SQL source. So, is it possible to construct a query to do the same as this?
SELECT ID FROM Types
UNION
SELECT 1
The best I've come up with is this:
List<int> OrgList = DBContext.Types.Select(b => b.ID).ToList();
OrgList.Add(1);
but I'd rather add the item beforehand and still have an IQueryable. Or is there a good reason to not do it this way?
You must get the data from the db and then add the new item like you have done in your code.
The only way to have an IQueryable would be to deffer the adding of the new item to the point were the query is resolved.
You can use Union:
var query = DBContext.Types.Select(b => b.ID).ToList().Union(new[]{1});
Not tested but it should work
Try Concat
var result = DBContext.Types.Select(p => p.ID)
.Concat(new List<int>() { 1 }).ToList();

Running a simple LINQ query in parallel

I'm still very new to LINQ and PLINQ. I generally just use loops and List.BinarySearch in a lot of cases, but I'm trying to get out of that mindset where I can.
public class Staff
{
// ...
public bool Matches(string searchString)
{
// ...
}
}
Using "normal" LINQ - sorry, I'm unfamiliar with the terminology - I can do the following:
var matchedStaff = from s
in allStaff
where s.Matches(searchString)
select s;
But I'd like to do this in parallel:
var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString));
When I check the type of matchedStaff, it's a list of bools, which isn't what I want.
First of all, what am I doing wrong here, and secondly, how do I return a List<Staff> from this query?
public List<Staff> Search(string searchString)
{
return allStaff.AsParallel().Select(/* something */).AsEnumerable();
}
returns IEnumerable<type>, not List<type>.
For your first question, you should just replace Select with Where :
var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString));
Select is a projection operator, not a filtering one, that's why you are getting an IEnumerable<bool> corresponding to the projection of all your Staff objects from the input sequence to bools returned by your Matches method call.
I understand it can be counter intuitive for you not to use select at all as it seems you are more familiar with the "query syntax" where select keyword is mandatory which is not the case using the "lambda syntax" (or "fluent syntax" ... whatever the naming), but that's how it is ;)
Projections operators, such a Select, are taking as input an element from the sequence and transform/projects this element somehow to another type of element (here projecting to bool type). Whereas filtering operators, such as Where, are taking as input an element from the sequence and either output the element as such in the output sequence or are not outputing the element at all, based on a predicate.
As for your second question, AsEnumerable returns an IEnumerable as it's name indicates ;)
If you want to get a List<Staff> you should rather call ToList() (as it's name indicates ;)) :
return allStaff.AsParallel().Select(/* something */).ToList();
Hope this helps.
There is no need to abandon normal LINQ syntax to achieve parallelism. You can rewrite your original query:
var matchedStaff = from s in allStaff
where s.Matches(searchString)
select s;
The parallel LINQ (“PLINQ”) version would be:
var matchedStaff = from s in allStaff.AsParallel()
where s.Matches(searchString)
select s;
To understand where the bools are coming from, when you write the following:
var matchedStaff = allStaff.AsParallel().Select(s => s.Matches(searchString));
That is equivalent to the following query syntax:
var matchedStaff = from s in allStaff.AsParallel() select s.Matches(searchString);
As stated by darkey, if you want to use the C# syntax instead of the query syntax, you should use Where():
var matchedStaff = allStaff.AsParallel().Where(s => s.Matches(searchString));

lambda equivalent to sql update with joins

I have 2 sets of data.
What would be the lambda syntax equivalent to this sql update statement ?
UPDATE Customers1
SET Customers1.Email = Customers2.Email
JOIN Customers2 ON Customers1.ID = Customers2.ID
Lambdas are just a way of writing anonymous methods: x => { body }. I assume you actually mean LINQ.
There is no equivalent, because the Q in LINQ stands for query. LINQ queries data, it doesn't change it.
As DanielHilgarth said just to use lambda or even LINQ is not enough here.
I assume you'd need something like:
foreach(var customer1 in customers1) {
var customer2 = customers2.FirstOrDefault(c2 => customer1.ID.Equals(c2.ID));
if (customer2 != null) customer1.Email = customers2.Email;
}
So, lambda is a chunk of the whole implementation.

Categories