LINQ Multiple order by when not using lambda expressions [duplicate] - c#

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Multiple “order by” in LINQ
I want to order some dataset by some field AND THEN some other field.
Using lambda expressions this would be easy (OrderBy.ThenBy), but how to do it when I have a syntax like this:
int maxQueries = int.MaxValue;
// finds the most search for queries
var ordered = from p in searchLogs
where !string.IsNullOrEmpty(p.SearchQuery)
group p by new
{
SearchQuery = p.SearchQuery
}
into pgroup
let count = pgroup.Count()
orderby count descending
select new
{
Count = count,
SearchQuery = pgroup.Key.SearchQuery
};
I can't seem to find a way which works after the decending keyword (like orderby count descending then searchquery)..
Any ideas?

Put a comma after descending and specify the next thing to sort by (optionally adding descending) and so on

Just to add some code to mlorbetske answer, if you have Customer class like this:
public class Customer
{
public string Name;
public DateTime MemberSince;
}
You could then perform an ordering like this:
var q = from c in Customers
orderby c.MemberSince.Date descending, c.Name
select c;

Related

c# linq Query how to write multiple And condition [duplicate]

This question already has answers here:
How to do joins in LINQ on multiple fields in single join
(13 answers)
Closed 2 years ago.
This is My Query in Linq
VAR x = FROM n IN _db.tbl_maint_activity_material_details
JOIN availablity IN _db.tbl_maint_item_availability ON n.mamd_lotno equals availablity.mia_lot_no && n. ////
Here im not able to countine my Code Please Help me
This is My SQL query
SELECT *
FROM tbl_maint_activity_material_details AS _material
JOIN tbl_maint_item_availability AS availablity
ON _material.mamd_maint_item_id = availablity.mia_maint_item_id
AND _material.mamd_lotno = availablity.mia_lot_no
WHERE _material.mamd_status = 24
To accomplish that, you have to build an object and use equals.
Something like:
on new { mia_lot_no = n.mamd_lotno, mamd_lotno = n.mamd_lotno } equals new { mia_lot_no = availablity.mia_lot_no, mamd_lotno = ... }
So that the equals will result true if the whole object is equal.

Linq - how to filter dataset based on data in another table?

I'm looking to filter the data in a dataset much like you'd do a where <value> in (select <value> from other_table where year=2016)
So I have a list of the "values":
var BUs = (from b in dc.BusinessUnits
where b.Year == int.Parse(ddlYears.SelectedValue)
orderby b.BuName
select new { b.BUID }).ToList();
So what I need to do is filter this dataset based on the BUID list returned in the BUs var.
IQueryable<Market> markets = (from p in dc.Markets
orderby p.MarketName
select p);
Help? I'm 100% new to linq so I need a concise solution.
Well if you Market entity has a BUID property and this property it's a primitive type (int, string..) or an enum, you can use Contains method:
var BUs = (from b in dc.BusinessUnits
where b.Year == int.Parse(ddlYears.SelectedValue)
orderby b.BuName
select b.BUID );
IQueryable<Market> markets = (from p in dc.Markets
where BUs.Contains(p.BUID)
orderby p.MarketName
select p);
The standard way of filtering by in memory id list is to use Enumerable.Contains method. But you need first to make sure your list contains ids - they way you wrote it it will contain anonymous type with a property called BUID, by changing the first query like this
int year = int.Parse(ddlYears.SelectedValue);
var BUIDs = (from b in dc.BusinessUnits
where b.Year == year
orderby b.BuName
select b.BUID).ToList();
and then use
var markets = (from p in dc.Markets
where BUIDs.Contains(p.BUID)
orderby p.MarketName
select p);
But note that this will be inefficient. Much better option would be to not use the list of BUIDs for filtering, but combining the 2 queries so the whole thing becomes a single query executed in the database, like this
var markets = (from p in dc.Markets
where dc.BusinessUnits.Any(bu => b.Year == year && b.BUID == p.BUID)
orderby p.MarketName
select p);
This is the exact equivalent of, if using your words, much like you'd do a "where in (select from other_table where year=2016)".

Linq not contains dynamic query [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Linq to SQL “not like” operator
How can I write a dynamic linq query with using not contains?
I use .Contains() instead of like. But what should I use instead of not like?
just use ! before the contains condition. Like
var myProducts = from p in products
where !productList.Contains(p.ID)
select p;
Some thing like this should help...
YourDataContext dc = new YourDataContext();
var query =
from c in dc.Customers
where !(from o in dc.Orders
select o.CustomerID)
.Contains(c.CustomerID)
select c;
Use ! operator. Like this:
private List<int> iList = new List<int>
{
1,2,3,4,5,6,7,8,9
};
if (!iList.Contains(888))
{
}

Check if item exists and return matched elements using .Contains() on anonymous type

I have a collection of dates (possibly duplicates) that I need to check against using .Contains() or a similar method.
I create an anonymous type like this:
var bookedDates = (from b in db.Bookings
where b.BookingDate > DateTime.Today
select new
{
Date = b.BookingDate,
StatusID = b.StatusId
});
I then have a collection of dates (d), and I need to test whether d exists within my anonymous type. This would be easy using a dictionary since I can use the .ContainsKey().
If a date exists within the anonymous type, I need to get the one or multiple items that correspond to the date I'm testing.
Is there a quick way to do this, I know I can do it by looping and testing each and every key but looking for a faster/more efficient way.
In essence, I'm looking for a dictionary that supports duplicate items.
If you just want to check whether you have the date already you can use a HashSet, then check the hashset in the following queries etc.:
HashSet<DateTime> dates = new HashSet<DateTime>();
foreach (var item in bookedDates)
dates.Add(item.Date);
..
if (dates.Contains(someDate))
{
//...
}
Edit:
I think you just want a lookup based on the items in your query:
var dateLookup = db.Bookings
.Where( b => b.BookingDate > DateTime.Today)
.ToLookup( p => p.BookingDate,
p => p.StatusId);
A lookup allows a collection of items for each key, so that might be what you are looking for.
Then you can just use it like this:
var statusIdsForToday = dateLookup[DateTime.Now.Date].ToList();
var distinctNames = bookedDates.Distinct();
Maybe I'm getting it wrong, but you can apply another LINQ query on your bookedDates, something like this:
DateTime searchDateTime = DateTime.Now; // or any other DateTime
var statusIds = (from b
in bookedDates
where b.Date == searchDateTime // or a similar comparison
select b.StatusID);
var statusIdsList = statusIds.ToList();
edit: if the search dates are from the same database then a join would be an option
var bookedIds = (from b
in db.Bookings
join dates in db.SearchDates on b.BookingDate equals dates
select b.StatusId);
(assuming that the dates to compare are located in db.SearchDates, if necessary, add a where dates > DateTime.Now or other restrictions on the dates)
var bookedDates = (from b in db.Bookings
where b.BookingDate > DateTime.Today
select new
{
date = b.BookingDate,
statusId = b.StatusId
}).GroupBy(x => x.date).Where(x => x.Count() > 1);
This should give you an IEnumerable of type IGrouping of type DateTime, StatusID type

Linq query with multiple where's [duplicate]

This question already has answers here:
Multiple WHERE clause in Linq
(3 answers)
Closed 2 years ago.
I am trying the to query my Status Update repository using the following
var result = (from s in _dataContext.StatusUpdates
where s.Username == "friend1" && s.Username == "friend2" etc...
select s).ToList();
Instead of using s.Username == "friendN" continuously is there anyway I can pass a list or array or something like that rather that specifying each one, or can I use a foreach loop in the middle of the query.
Thanks
If you only need to check whether the Username property has some specified value, you can create a list of the values and then use method such as All or Any to check if some condition holds for any/all elements of the array.
Your example looks a bit suspicious though - the user name s.Username cannot be equal to multiple different strings. Did you want to check whether it is equal to any of the (specified) names? That could be written like this:
var friends = new[] { "friend1", "friend2", ... };
var result =
from s in dc.StatusUpdates
where friends.Any(fr => s.Username == fr)
select s;
This returns all status updates such that the Username property is equal to any of the specified friend names (specified as an array, but you could use any IEnumerable<string>).
Yo could do it like this:
IQueryable<s> query= _dataContext.StatusUpdates;
foreach (var item in names)
{
query = query.Where(p=>p.Username == item);
}
List<s> result = query.ToList();
I think I mucked with some data types of yours but this should be close:
var names = new List<string>();
// populate names
var updates = new List<StatusUpdate>();
// populate updates
var result = (from s in updates
where names.Contains(s.ToString())
select s).ToList();

Categories