i have custom a collection LoanOptionsProgramVersionList which has bolean property Configured,string Description and Code.While insert and delete from the collection i want sort the collection in the below order. So one record inserted to database configured become yes. When deleted Configured become "No". So it Notify property.
sort by configured
then by description
then by code
i have tried the below code After insert.
IOrderedEnumerable<ProgramVersionRecord> orderedList =
LoanOptionsProgramVersionList
.OrderByDescending(p => p.ProgramVersionConfigured == true);
Also below code for deletion
IOrderedEnumerable<ProgramVersionRecord> orderedList =
LoanOptionsProgramVersionList.OrderBy(p => p.Description);
Any help will be appreciated.
Use ThenBy
IOrderedEnumerable<ProgramVersionRecord> orderedList = LoanOptionsProgramVersionList
.OrderByDescending(p => p.ProgramVersionConfigured) // configured has priority
.ThenBy(p => p.Description)
.ThenBy(p => p.Code);
When ordering by ProgramVersionConfigured property use this property instead of result of comparison with boolean. Also use ThenBy to add another sorting:
LoanOptionsProgramVersionList.OrderByDescending(p => p.ProgramVersionConfigured)
.ThenBy(p => p.Description)
.ThenBy(p => p.Code)
Related
I'm still trying to get the hang of NHibernate. I'm doing some queries with projections, and so far I managed to come up with this:
var restrictions = Restrictions.Conjunction();
// add some restrictions
var qo = Session.QueryOver(() => tenantAlias)
.JoinAlias(x => x.Customer, () => customerAlias)
.Where(restrictions)
.SelectList(list => list
.Select(() => tenantAlias.Id).WithAlias(() => item.TenantId)
.Select(() => tenantAlias.DomainName.Value).WithAlias(() => item.DomainName)
.Select(() => customerAlias.Code.Value).WithAlias(() => item.CustomerCode)
.Select(() => customerAlias.DisplayName).WithAlias(() => item.CustomerName)
.Select(() => tenantAlias.ActivationPeriod.From).WithAlias(() => item.ActivationPeriodFrom)
.Select(() => tenantAlias.ActivationPeriod.Until).WithAlias(() => item.ActivationPeriodUntil)
.Select(() => tenantAlias.PurchasedLicenses.Value).WithAlias(() => item.PurchasedLicenses)
)
.TransformUsing(Transformers.AliasToBean<TenantQueryResult.Item>());
var items = await qo.ListAsync<TenantQueryResult.Item>();
Following a DDD approach, Tenant is an aggregate root and Customer an entity, and they have a one-to-one relationship. So far, this query is working beautifully.
Now, however, I would like to order the result set by customer's displayname property. I found there's an OrderBy method, so I thought it simple enough to add the following line:
.OrderBy(() => customerAlias.DisplayName)
But alas, this doesn't compile. The reason is that the query over always returns an instance of IQueryOver<T, T>, but the OrderBy clause returns IQueryOver<T> only. And IQueryOver<T> does not have a SelectList or TransformUsing or even ListAsync method. So I don't get how OrderBy clauses should work. The NHibernate documentation [1] doesn't provide an example, and Googling only got me simple examples with Cats, but never with joins or transforms or projections.
The same thing happens when I try to add paging to my query. Both Take and Skip methods are available, but they have the same problem, both return IQueryOver<T> instead of IQueryOver<T, T>.
The question is, then, how I'm supposed to add ordering and paging clauses with QueryOver API, when using joins and projections? Thanks in advance.
[1] http://nhibernate.info/doc/nhibernate-reference/queryqueryover.html
We have to add direction ASC or DESC. So instead of this
.OrderBy(() => customerAlias.DisplayName)
.TransformUsing(Transformers.AliasToBean<TenantQueryResult.Item>());
We have to add .Asc or .Desc
.OrderBy(() => customerAlias.DisplayName)
.Asc
.TransformUsing(Transformers.AliasToBean<TenantQueryResult.Item>());
I have the following line:
orderBaseData.Single(o => o.Id == order.Id).OrderMessages.Count;
I want to filter this a bit more. Each OrderMessage has a variable called hideFromUser, and I want to get the count of the OrderMessages where this is set to FALSE only.
Thanks in advance,
Bob
Use Where on OrderMessages
orderBaseData
.Single(o => o.Id == order.Id)
.OrderMessages
.Where(x => !x.hideFromUser)
.Count();
In order to retrieve the data efficiently in a single query, instead of relying on LazyLoading the OrderMessages afterwards, you could use the following:
orderBaseData
.Where(o => o.Id == order.Id)
.Select(o => o.OrderMessages.Where(x => !x.hideFromUser).Count())
.Single();
This approach is mostly interesting when orderBaseData is some IQueryable targeting a database. If all the data are already in memory, then it is not really better or worse than the other approaches.
I have a list of objects that I need some duplicates removed from. We consider them duplicates if they have the same Id and prefer the one whose booleanValue is false. Here's what I have so far:
objects.GroupBy(x => x.Id).Select(x => x.Where(y => !y.booleanValue));
I've determined that GroupBy is doing no such grouping, so I don't see if any of the other functions are working. Any ideas on this? Thanks in advance.
You can do this:
var results =
from x in objects
group x by x.Id into g
select g.OrderBy(y => y.booleanValue).First();
For every Id it finds in objects, it will select the first element where booleanValue == false, or the the first one (if none of them have booleanValue == false).
If you prefer fluent syntax:
var results = objects.GroupBy(x => x.Id)
.Select(g => g.OrderBy(y => y.booleanValue).First());
Something like this should work:
var result =
objects.GroupBy(x => x.Id).Select(g =>
g.FirstOrDefault(y => !y.booleanValue) ?? g.First())
This assumes that your objects are of a reference type.
Another possibility might be to use Distinct() with a custom IEqualityComparer<>.
This partially answers the question above, but I justed need a really basic solution:
objects.GroupBy(x => x.Id)
.Select(x => x.First())
.ToArray();
The key to getting the original object from the GroupBy() is the Select() getting the First() and the ToArray() gets you an array of your objects, not a Linq object.
I have code like this:
.Where(o => o.Parents.Contains(name))
The above code does not work because Parents contain a list of Parent objects, which in turn have a property Name. I want to check against the Name property, but it's a list so how could I do this check? So I want the Where to be true when any of the Parent objects in the list have Name property set to name.
Try the following code snippet:
.Where(o => o.Parents.Any(p => p.Name == name))
There's a simple fix for this: use more LINQ.
.Where(o => o.Parents.Any(p => p.Name == name))
As an alternative, you could use the slightly more verbose (but equally lazy)
.Where(o => o.Parents.Select(p => p.Name).Contains(name))
You can use .Any to check for a specific condition inside a collection of objects where you want to check for a specific property.
.Where(o => o.Childs.Any(child => child.Name == o.Name));
I have a list of objects with field UserID, Property:
I would like to order the list by most shared property value. So if every user has Property= "Popular", that should come up first. If everyone but one user has Property="Second" that should come up second in list...
even if its only used once for each user.
I would do distinct() on each possible Property and but that doesnt seem efficient with many possible Property.
You can use a grouping on Property, order the groups by the number of counts in each group and then flatten the list again using SelectMany():
var items = myList.GroupBy(x => x.Property)
.OrderByDescending(g => g.Count())
.SelectMany(g => g);
.ToList();
From your question its not quite clear to me whether you want duplicates to show up or not and if you are at all interested in the UserID. If not, you can just select the keys of the groups to give you a List<string> of unique Property values in the desired order:
var props = myList.GroupBy(x => x.Property)
.OrderByDescending(g => g.Count())
.Select(g => g.Key);
.ToList();
Edit:
It seems like this would be more what you are actually are looking for - groups are are ordered by the number of unique users that have a given property.
var props = myList.GroupBy(x => x.Property)
.OrderByDescending(g => g.Select(x=> x.UserID)
.Distinct()
.Count())
.Select(g => g.Key);
.ToList();