LINQ OrderBy query - c#

I have the following that pulls through a list of suppliers:
public List<tblSupplierPerformance> GetSupplierInfo(string memberid, string locationid, string supplieridname)
{
MyEntities suppliers = new MyEntities();
var r = (from p in suppliers.tblSupplierPerformances
where p.MemberId == memberid && p.LocationId == locationid
orderby p.TotalPurchaseQuantity
select p)
.Distinct();
if (supplieridname != "0")
r = r.Where(p => p.SupplierIDName == supplieridname);
return r.ToList();
}
However, when this runs, the orderby doesn't seem to be ordering.
I think, think, I need to implement the orderby at the "return r." stage, but I don't really know how to do this or I could be very much wrong all over the shop!
Any pointers gladly received.

I suspect it's the Distinct call which is messing up the ordering... although as you're not joining or doing anything like that, I'm not sure why you need distinct - isn't each entity naturally distinct?
Anyway, you could certainly move the ordering to the return statement:
return r.OrderBy(p => p.TotalPurchaseQuantity).ToList();

Yes, you need to implement order by in the return
return r.ToList().OrderBy(o => o.Column1);

Related

Include("myTable") in Linq to Entities in Silverlight

I need help, I have a method to Access to my Orders table:
public IQueryable<Orders> GetOrders()
{
return this.ObjectContext.Orders.Include("UnitDetail");
}
it Works very well, and I can see it from the window Data Source, and can see Orders and UnitDetail from here
But I need make some considerations for the selected rows, so I made the next method:
public IQueryable<Orders> GetOpenOrders(string _iduni)
{
ObjectSet<Orders> orders = this.ObjectContext.Orders;
ObjectSet<Estatus> estatus = this.ObjectContext.Estatus;
ObjectSet<DetailUnit> units = this.ObjectContext.DetailsUnit;
ObjectSet<ServiceType> servicetype = this.ObjectContext.ServiceType;
var query =
(from o in orders
join e in estatus on o.ID equals e.IDOrder
join u in units on o.IDUni equals u.IDUni
join t in servicetype on u.IDType equals t.IDType
where o.IDUni.Equals(_iduni)
&& !estatus.Any(oe => (oe.Estatus == "CANCELADA" || oe.Estatus == "CERRADA")
&& oe.IDOrder == o.ID)
select o).Distinct();
return query.AsQueryable();
}
This show me the correct recs, but what happend? why I don't see UnitDetail, when I inspect the result UnitDetail is null, how I can do for put the Include clausule in this new method??
Thanks a lot in advance
Because you haven't put the Include in your new method anywhere.
EDITED: to remove the unused joins.
You should be able to just use Include as you did in your GetOrders method, and so have it as a part of your existing orders variable. You are not actually using those joins anywhere, are you intending to?
Like this:
public IQueryable<Orders> GetOpenOrders(string _iduni)
{
var query =
(from o in this.ObjectContext.Orders.Include("UnitDetail")
where o.IDUni.Equals(_iduni)
&& !this.ObjectContext.Estatus.Any(oe => (oe.Estatus == "CANCELADA" || oe.Estatus == "CERRADA")
&& oe.IDOrder == o.ID)
select o).Distinct();
return query.AsQueryable();
}

C#/LINQ to SQL - order combined results from two different result sets

The sad part is, I've done this before. I remember figuring this out. Today, I can't seem to recall how to do this.
So you have this list:
public List<taters> getTaters(){
var firstTaters = from s in n.veggies
where s.active == true
select s.html;
var secondTaters = from s in n.roots
where s.active == true
select s.html;
//now here I want to do something to combine the two
//(e.g. a Concat or some such) and
//THEN I want to order the concatenated list of results
//by 'date_created' descending.
}
Question in above comments. How do I order them AFTER joining them together?
firstTaters.Concat(secondTaters)
.OrderByDescending(html => html.date_created)
also try to use concatenation on two sets before filtering, to avoid code duplication (may be slower, but is more maintainable)
public IEnumerable<taters> getTaters()
{
return from s in n.veggies.Concat(n.roots)
where s.active == true
orderby s.html.date_created descending
select s.html;
}
Don't forget to call ToList or change signature to return IQueryble<taters> or IEnumerable<taters>
Use Concat, or use Union if you want distinct results
var concated =
firstTaters.Concat(secondTaters).OrderByDescending(html => html.date_created);
//Gives distinct values
var unioned =
firstTaters.Union(secondTaters).OrderByDescending(html => html.date_created);
Or you can do this like in the bellow example:
public List<taters> getTaters(){
var firstTaters = from s in n.veggies
where s.active == true
select s.html;
var secondTaters = from s in n.roots
where s.active == true
select s.html;
return (
from first in firstTaters
join second in secondTaters on secondTaters.someField equals second.someField
select new
{
....
....
}
).toList();
}
Just add this :
return firstTaters.Concat(secondTaters).OrderByDescending(el => el.DateCreated);

Linq Help please.. Direct casting to Object instead of Var

I've always ignored the need for LINQ by iterating over objects but recently decided its time to leave behind the old school methods and get with the times.
I'm wondering if someone can help me simplify the below code by firstly, using Lambda instead of old school Linq and secondly, the below code will always return only 1 value.. How can I cast directly to the correct type (Player) in this case without having to iterate again?
MyEntities entity = new MyEntities();
Guid selectedPlayerID = Guid.Parse(lbPlayers.SelectedItem.Value);
var player = from n in entity.Players
where n.ID == selectedPlayerID
select n;
foreach (var item in player)
{
tbPlayerSurname.Text = item.Name;
tbPlayerName.Text = item.Surname;
}
If entity.Players contain Player objects you can simply specify
IEnumerable<Player> players = entity.Players
.Where(p => p.ID == selectedPlayerID);
I was having trouble understanding your post so my initial answer was to actually select only one (and reading comments i see that is what you wanted) which you could do like this:
Player player = entity.Players.Single(p => p.ID == selectedPlayerID);
This throws and error if there are not excatly one, you could use SingleOrDefault and check for null, or even FirstOrNull, in which case you risk swallowing a potential error if there were more than one and that is supposed to get caught
var blahs = entity.Players.Where(x => x.ID == selectedPlayerID)
.Select(x => new blah() { Name = x.Name, Text = x.Surname);
This gives you an IEnumerable<Blah>.
Does it make sense?
You can use:
entity.Players.Single(n=>n.ID==selectedPlayerId);
if you think it might not exist use SingleOrDefault (and check the return value being different from default, null in case of classes).
if you care only about the first one use First or FirstOrDefault instead.
Try this code below if **entity.Players is of type List<Player>
List<Player> selectedPlayers = (from n in entity.Players
where n.ID == selectedPlayerID select n).ToList();
And if entity.Players is not of type List<Player>
List<Player> selectedPlayers = (from n in entity.Players
where n.ID == selectedPlayerID
select new Player() { Name = n.Name, Surname = n.Surname } );

How to cast a Linq Dynamic Query result as a custom class?

Normally, I do this:
var a = from p in db.Products
where p.ProductType == "Tee Shirt"
group p by p.ProductColor into g
select new Category {
PropertyType = g.Key,
Count = g.Count() }
But I have code like this:
var a = Products
.Where("ProductType == #0", "Tee Shirt")
.GroupBy("ProductColor", "it")
.Select("new ( Key, it.Count() as int )");
What syntax could I alter to produce identical results, i.e., how do I do a projection of Category from the second Linq statement?
I know in both that g and it are the same and represent the entire table record, and that I am pulling the entire record in just to do a count. I need to fix that too. Edit: Marcelo Cantos pointed out that Linq is smart enough to not pull unnecessary data. Thanks!
Why would you have to do it at all? Since you still have all of the information after the GroupBy call, you can easily do this:
var a = Products
.Where("ProductType == #0", "Tee Shirt")
.GroupBy("ProductColor", "it")
.Select(c => new Category {
PropertyType = g.Key, Count = g.Count()
});
The type of Products should still flow through and be accessible and the regular groupings/filtering shouldn't mutate the type that is flowing through the extension methods.

Any Way to Use a Join in a Lambda Where() on a Table<>?

I'm in my first couple of days using Linq in C#, and I'm curious to know if there is a more concise way of writing the following.
MyEntities db = new MyEntities(ConnString);
var q = from a in db.TableA
join b in db.TableB
on a.SomeFieldID equals b.SomeFieldID
where (a.UserID == CurrentUser &&
b.MyField == Convert.ToInt32(MyDropDownList.SelectedValue))
select new { a, b };
if(q.Any())
{
//snip
}
I know that if I were to want to check the existence of a value in the field of a single table, I could just use the following:
if(db.TableA.Where(u => u.UserID == CurrentUser).Any())
{
//snip
}
But I'm curious to know if there is a way to do the lambda technique, but where it would satisfy the first technique's conditions across those two tables.
Sorry for any mistakes or clarity, I'll edit as necessary. Thanks in advance.
Yes, you can do this with extension methods. Note that you might get a more concise query by filtering each table first, though I suspect SQL Server would optimize it that way anyway.
if (db.TableA.Where( a => a.UserID == CurrentUser )
.Join( db.TableB.Where( b => b.MyField == Convert.ToInt32(MyDDL.SelectedValue) ),
o => o.someFieldID,
i => i.someFieldID,
(o,i) => o )
.Any()) {
...
}

Categories

Resources