Orderby and Linq - linq

How can i add orderby to this:
return (from m in response["holder"].Children()
orderby m["name"]
select new SelectListItem
{
Text = m["name"].ToString(),
Value = m["name"].ToString()
}).ToList();
The problem is that the json returned in the response variable has a list of names, all of them have an uppercase first letter apart from one so they all get ordered fine except the one with the lower case which gets stuck at the bottom of the SelectListItem list.
Any ideas?
Thanks in advance..
EDIT:
Additional info - i am using JSON.NET to parse the json response. And the response variable is a JObject.

You'll need to normalize the data during your orderby. In my example I've chosen to use the ToUpperInvariant() method:
return (from m in response["holder"].Children()
orderby m["name"].ToUpperInvariant()
select new SelectListItem
{
Text = m["name"].ToString(),
Value = m["name"].ToString()
}).ToList();
I'm also assuming that m["name"] is already a String object. If it's not, change the line to:
orderby m["name"].ToString().ToUpperInvariant()

Maybe something like this:
return (from m in response["holder"].Children()
orderby m["name"].ToString().ToLower()
select new SelectListItem
{
Text = m["name"].ToString(),
Value = m["name"].ToString()
}).ToList();

When using the OrderBy method in the method syntax, you can specifiy a StringComparer. Passing a StringComparer that ignores casing solves your issue:
response["holder"]
.Children()
.OrderBy(m => m["name"], StringComparer.CurrentCultureIgnoreCase);

response["holder"]
.Children()
.OrderBy(m => m["name"] as String, StringComparer.CurrentCultureIgnoreCase)
.Select(m => new SelectedListItem
{
Text = m["name"].ToString(),
Value = m["name"].ToString())
})
.ToList();

return response["holder"].Children()
.Select(m => m.FirstCharToUpper())
.OrderBy(m => m["name"].ToString())
.Select(m => new SelectedListItem{
Text = m["name"].ToString(),
Value = m["name"].ToString()
})
.ToList();
static class Utility
{
public static string FirstCharToUpper(this string s)
{
return s.First().ToString().ToUpper() + string.Join("", s.Skip(1));
}
}

Related

How can I add Sum from another Table in my Model?

So I have my View setup like this in the controller:
public ActionResult View(Guid projectID)
{
OnboardModel model = context.onboard_projectInfos.Where(x => x.projectID == projectID).Select(x =>
new OnboardModel()
{
propertymanagername = x.propertymanagername,
propertymanagercontactemail = x.propertymanagercontactemail,
date_modified = (DateTime)x.date_modified,
projectmanagercontactnumber = x.projectmanagercontactnumber,
Developer = x.onboard_projectCreate.Developer,
status1 = x.onboard_projectCreate.status1,
ProjectName = x.onboard_projectCreate.ProjectName
}).SingleOrDefault();
var pix = projectID.ToString();
context.onboard_BuildingInfos.Where(x => x.buildprojectID == pix).GroupBy(x => x.buildprojectID).Select(g => {
model.totalres = g.Sum(b => b.numberofres);
model.totalcom = g.Sum(b => b.numberofcommer);
});
return View(model);
}
Problem is grabbing the sum of numberofres and numberofcommer from BuildingInfos.
Using .Select gives me the error:
Error CS0411 The type arguments for method 'Queryable.Select(IQueryable, Expression>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
How to I write this LINQ statement correctly?
Thanks.
You cannot modify an object within a select (you can only create a new object). Further, you can't add new properties to an existing object.
We'll assume that OnboardModel defines the totalres and totalcom properties.
var query = context.onboard_BuildingInfos
.Where(x => x.buildprojectID == pix)
.GroupBy(x => x.buildprojectID);
foreach(var g in query)
{
model.totalres = g.Sum(b => b.numberofres);
model.totalcom = g.Sum(b => b.numberofcommer);
}

Replacing empty values with a default value in a Linq to Entities query

In the Linq to Entities query below I need to place a default value in the x.Number in the returned value if the query returns 0 OfficeTelephone objects. I have tried
x.Number??"555-1212" but that throws an error.
from c in Contacts
.Where(a => a.LastName.Contains("ANDUS")).Take(10)
select new
{
Id = c.Id,
OfficeTelephone = c.Telephones.Where(a=>a.TelephoneType.Name.Contains("Office")).Select(x => new { x.AreaCode, x.Number, x.TelephoneType, x.Primary })
}
I've tried something like:
from c in Contacts
.Where(a => a.LastName.Contains("ANDUS")).Take(10)
select new
{
Id = c.Id,
OfficeTelephone = c.Telephones
.Where(a=>a.TelephoneType.Name.Contains("Office"))
.Select(x => new { x.AreaCode, x.Number, x.TelephoneType, x.Primary })
.DefaultIfEmpty()}
But I'm not sure how to push a default object into the DefaultIFEmpty()
Use DefaultIfEmpty and pass a default instance with those value which you would want by default i.e. if no rows are returned.
try it like this:
Contacts.Where(a=>a.LastName.Contains("ANDUS"))
.Take(10)
.Select(x => new
{
Id = x.Id,
OfficeTelephone = x.Telephones
.Where(a=> a.Telephone.Name.Contains("Office"))
.Select(b=> new Telephone
{
b.AreaCode,
b.Number,
b.TelephoneType,
b.Primary
})
.DefaultIfEmpty(new Telephone())
});
where I've assumed that typeof(x.Telephones) == typeof(List<Telephone>)

Filter SelectListItem value using some condition

I have one SelectListItem for DropDownList. I have to filter based on some condition. If I try adding the condition then its gives me an error like this (LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression). I ll be adding that code here. Please guide me to solve this.
Code
IEnumerable<SelectListItem> IssueId = (from txt in Db.Issues where txt.BibId == BibId
select new SelectListItem()
{
Text = txt.Description,
Value = txt.Id.ToString(),
Selected = true,
});
SelectList IssueIds = new SelectList(IssueId, "Value", "Text");
ViewBag.IssueId = IssueIds;
Thanks
Try this:
LINQ2EF does not know ToString() but after AsEnumerable() you'll get a local collection when ToString() is implemented.
IEnumerable<SelectListItem> IssueId =
(from txt in Db.Issues.Where(e => e.BibId == BibId).AsEnumerable()
select new SelectListItem()
{
Text = txt.Description,
Value = txt.Id.ToString(),
Selected = true
});
Linq To Sql can't generate TSQL for txt.Id.ToString()
You will need to iterate the result instead after executing the query, or cast to Enumerable as xeondev suggests.
That extension does not seem to be sorted by linq to Entities but you could just do the mapping once you have the issues, e.g.
var issues = (from issue in Db.Issues
where issue .BibId == BibId
select issue ).ToList();
IEnumerable<SelectListItem> IssueId = (from txt in issues
where txt.BibId == BibId
select new SelectListItem()
{
Text = txt.Description,
Value = txt.Id.ToString(),
Selected = true,
});

LINQ ForEach with Replace

I am trying to replace a string date value "01/01/1700" with an empty string in LINQ.
The date is of type string.
Something like this but I cant get it to work.
Query<Client>(sql).ToList().ForEach(x => x.DateOfBirth =
x.DateOfBirth.Replace("01/01/1700", ""));
This code works but its not LINQ.
var result = Query<Client>(sql).ToList();
foreach (var client in result)
{
if (client.DateOfBirth == "01/01/1700")
{
client.DateOfBirth = "n/a";
}
}
Thanks for your help.
The problem is the ToList(). The result is not visible in the variable you use afterwards.
Try out the following:
var list = Query<Client>(sql).ToList();
list.ForEach(l => l.DateOfBirth = l.DateOfBirth.Replace("01/01/1700", "n/a"));
Should work fine. Use the list variable afterwards.
var result = Query<Client>(sql).ToList();
result.ForEach(l => l.DateOfBirth = l.DateOfBirth.Replace("01/01/1700", "n/a"));
Your code assumes that changes made to an object in a List will be reflected in the Query<Client> that the object came from. Apparently this is not the case. One thing you could try is assigning the list before calling ForEach() and using the list from that point on:
var clients = Query<Client>(sql).ToList();
clients.ForEach(x => x.DateOfBirth = x.DateOfBirth.Replace("01/01/1700", ""));
Also, ForEach is not a LINQ operator. It is a method in the List class. Unlike LINQ operators, it will modify the list that called it and will not return anything. The way to "modify" data with LINQ is by using select:
var clients = (from client in Query<Client>(sql).ToList()
select new Client(client)
{
DateOfBirth = client.DateOfBirth.Replace("01/01/1700", "")
}).ToList();

Selecting related pairs LINQ

I'm using LINQ to manipulate a datatable. I have 3 columns - I would like group by one and then select the remaining 2 columns together. At the moment I have something like this
var query = reportDataTable.AsEnumerable()
.GroupBy(c => c["Code"])
.Select(g =>
new {
Code = g.Key,
Rank = g.Select(f => new
{ f["rank"],
f["Name"]}).ToArray()
});
but I get issues due to anonymous types. I know this syntax would work if I could reference the the column headers directly (in say a list or w/e). How can I get around this with DataTables? Cheers.
Edit:
Well I'd like to be able to reference the fields later when I come to populate the data into a different datatable:
foreach (var q in query)
{
DataRow df = dp.NewRow();
df["Code"] = q.Code;
foreach (var rank in q.Rank)
{
df[rank.name] = rank.rank;
}
dp.Rows.Add(df);
}
define your Rank fields, Also if you have a class for it, call related class constructor,
you can see this in bellow code, before ToArray.
var query = reportDataTable.AsEnumerable()
.GroupBy(c => c["Code"])
.Select(g =>
new { Code = g.Key, Rank =
g.Select(f => new { rank = f["rank"], name = f["Name"]})
.ToArray() });

Resources