c# Web Service Sorting Result - c#

I am trying to sort this select by vehicle.DateRegistered but its really confusing me and nothing i seem to do works. Any help would be much appreciated.
var lookupValues = vehicles
.Select(vehicle =>
new LookupValue()
{
Id = vehicle.Id,
Description = vehicle.RegistrationNumber + " " +vehicle.DateRegistered.ToString("dd/mm/yyyy"),
Data = Json.GetString(vehicle),
Active = true
});
return lookupValues;
Thanks Austin

Use the OrderBy extension method:
var lookupValues = vehicles.OrderBy(v => v.DateRegistered).Select(.....);

You can try with this code - based on OrderBy Linq operator
lookupValues.OrderBy(a=> a.DateRegistered);
Nota : Add DateRegistered in your selector
Or also you can use this
var lookupValues = vehicles
.OrderBy(a => a.DateRegistered)
.Select(vehicle =>
new LookupValue()
{
Id = vehicle.Id,
Description = vehicle.RegistrationNumber + " " +vehicle.DateRegistered.ToString("dd/mm/yyyy"),
Data = Json.GetString(vehicle),
Active = true
});
return lookupValues;
Nota : you define direction of order : descending or ascending

var lookupValues = vehicles
.OrderBy(vehicle => vehicle.DateRegistered)
.Select(vehicle =>
new LookupValue()
{
Id = vehicle.Id,
Description = vehicle.RegistrationNumber + " " +vehicle.DateRegistered.ToString("dd/mm/yyyy"),
Data = Json.GetString(vehicle),
Active = true
});
return lookupValues;

Related

Selecting from multiple lists in model and putting it in a dropdown

I am trying to populate my dropdownlist by doing this
var componentList = (from c in model.Components
select new
{
compID = c.ID,
compName = c.CompID + ":" + c.ComponentName
}).OrderBy(x => x.compName).ToList();
(from sc in model.ComponentSubComps
select new
{
compID = sc.ID,
compName = sc.SubCompID + ":" + sc.SubCompName
}).OrderBy(x => x.compName).ToList();
ViewBag.Components = new SelectList(componentList, "compID", "compName");
But it is only pulling the data from the model.Components list in the model. How can I make it so it also pulls from the model.ComponentSubComps list as well?
I don't know if you want to combine the components and sub-components or not. Combining them as a dangerous potential to mix up the IDs, assuming if they're in a separate table in your database and their primary keys are just incremental integer values.
This would become a serious bug if it's not being taken care of first. If their IDs could be the same, you might have to go with two dropdowns (one for components and one for sub-components) instead of one.
If you have to combine both of them, it sounds like you almost have to combine something uniquely with the IDs, assign them as different groups and parse the IDs when you receive from post back:
// Define the Groups
var componentGroup = new SelectListGroup { Name = "Component" };
var subComponentGroup = new SelectListGroup { Name = "SubComponent" };
var componentOptions = model.Components
.OrderBy(x => x.ComponentName)
.Select(x => new SelectListItem
{
Value = "c:" + x.CompID,
Text = x.CompID + ":" + x.ComponentName,
Group = componentGroup
});
var subComponentOptions = model.ComponentSubComps
.OrderBy(x => x.SubCompName)
.Select(x => new SelectListItem
{
Value = "sc:" + x.SubCompID,
Text = x.SubCompID + ":" + x.SubCompName,
Group = subComponentGroup
});
var dropdownOptions = new List<SelectListItem>();
dropdownOptions.AddRange(componentOptions);
dropdownOptions.AddRange(subComponentOptions);
Then when the user makes a selection and post the dropdown value back to the sever, you might have to parse the selected dropdown value and see if the ID belongs to component or sub-component.
If there is no difference between components and sub-components, then you can just combine them as easily as:
var componentOptions = model.Components
.OrderBy(x => x.ComponentName)
.Select(x => new SelectListItem
{
Value = x.CompID,
Text = x.CompID + ":" + x.ComponentName
});
var subComponentOptions = model.ComponentSubComps
.OrderBy(x => x.SubCompName)
.Select(x => new SelectListItem
{
Value = x.SubCompID,
Text = x.SubCompID + ":" + x.SubCompName
});
// This is your SelectList. I would highly recommend you build a strongly-typed
// view model and use it instead of ViewBag.
var dropdownOptions = new List<SelectListItem>();
dropdownOptions.AddRange(componentOptions);
dropdownOptions.AddRange(subComponentOptions);
You have two statements. The result from the first statement you store in componentList but the result from the second statement isn't stored anywhere.
Try to add the result from the second statement to componentList.
Probably List<T>.AddRange(IEnumerable<T>) is the best option.
Edit:
var componentList = (from c in model.Components
select new
{
compID = c.ID,
compName = c.CompID + ":" + c.ComponentName
}).OrderBy(x => x.compName).ToList();
var secondResult = (from sc in model.ComponentSubComps
select new
{
compID = sc.ID,
compName = sc.SubCompID + ":" + sc.SubCompName
}).OrderBy(x => x.compName).ToList();
componentList.AddRange(secondResult);
ViewBag.Components = new SelectList(componentList, "compID", "compName");
You can write the queries with entities and get:
var componentList = model.Components.Select(c => new Components
{
compID = c.ID,
compName = c.CompID + ":" + c.ComponentName
}).OrderBy(x => x.compName).ToList();
var componentList1 = model.ComponentSubComps.Select(c => new Components
{
compID = c.ID,
compName = c.SubCompID + ":" + c.SubCompName
}).OrderBy(x => x.compName).ToList();
componentList.AddRange(componentList1);
ViewBag.Components = new SelectList(componentList, "compID", "compName");

EnumerateFiles in Linq

I have LINQ to Entities does not recognize the method 'System.Collections.Generic.IEnumerable1[System.String] EnumerateFiles(System.String)' method, and this method cannot be translated into a store expression.` error. I need to get links to images from folders, I get ID from the database.
// Collect flat items and add in List<>
var nearestItems = from item in _db.Flats
select new listItem()
{
Price = item.Price,
Address = item.Address,
Bathroom = item.Bathroom,
BesprovodnoiInternet = item.BesprovodnoiInternet,
City = item.City,
FloorAll = item.FloorAll,
FloorCurrent = item.FloorCurrent,
Funiture = item.Funiture,
Kondicioner = item.Kondicioner,
PartyFree = item.PartyFree,
RoomQuantity = item.RoomQuantity,
TipArendy = item.TipArendy,
TV = item.TV,
ImagesString = Directory.EnumerateFiles(Server.MapPath("~/Content/Prop/" + item.FlatID + "/"))
.Select(fn => "~/Content/Prop/" + item.FlatID + "/" + Path.GetFileName(fn)).ToList()
};
Are there fix for this or alternate code?
Your LINQ query should be translated to SQL query to run on SQL Server. It is obvious that the engine cant translate Directory.EnumerateFiles to SQL query.
You can add new property FlatId to your listItem and try this:
// Collect flat items and add in List<>
var nearestItems = (from item in _db.Flats
select new listItem()
{
Price = item.Price,
Address = item.Address,
Bathroom = item.Bathroom,
BesprovodnoiInternet = item.BesprovodnoiInternet,
City = item.City,
FloorAll = item.FloorAll,
FloorCurrent = item.FloorCurrent,
Funiture = item.Funiture,
Kondicioner = item.Kondicioner,
PartyFree = item.PartyFree,
RoomQuantity = item.RoomQuantity,
TipArendy = item.TipArendy,
TV = item.TV,
FlatId = item.FlatID,
}).ToList();
foreach(var item in nearestItems)
{
item.ImagesString = Directory.EnumerateFiles(Server.MapPath("~/Content/Prop/" + item.FlatId + "/"))
.Select(fn => "~/Content/Prop/" + item.FlatId + "/" + Path.GetFileName(fn)).ToList();
}
EntityFramework will build query based on your LINQ which will execute in the database. So there are some constarints while using LINQ to Entity. How must EF convert this code to the database query? Directory.EnumerateFiles
There is no way.
So, you must select only required properties and then change them as you wish in .net:
var nearestItems = (from item in _db.Flats
select new listItem()
{
Price = item.Price,
Address = item.Address,
Bathroom = item.Bathroom,
BesprovodnoiInternet = item.BesprovodnoiInternet,
City = item.City,
FloorAll = item.FloorAll,
FloorCurrent = item.FloorCurrent,
Funiture = item.Funiture,
Kondicioner = item.Kondicioner,
PartyFree = item.PartyFree,
RoomQuantity = item.RoomQuantity,
TipArendy = item.TipArendy,
TV = item.TV,
FlatId = item.FlatID,
}).ToList();
And in you class change the get accessor of your property ImagesString:
public List<string> ImagesString
{
get
{
return Directory.EnumerateFiles(Server.MapPath("~/Content/Prop/" + FlatID + "/"))
.Select(fn => "~/Content/Prop/" + FlatID + "/" + Path.GetFileName(fn))
.ToList();
}
}

Linq query rewriting

This has really stumped me...
I have two queries..
This one does NOT work, with the error,
"LINQ to Entities does not recognize the method GetAllCustomers()' method, and this method cannot be translated into a store expression."
results = theDocuments.Select(x => new DocumentModel()
{
document_id = x.document_id,
document_type = x.document_type,
franchisee_id = x.franchisee_id,
customer_id = x.customer_id,
address = x.address,
area_id = x.area_id,
***HERE***customer_name = outletService.GetAllCustomers().Where(xx => xx.id == x.customer_id).First().name
}).OrderBy(x => x.document_id);
Now rewriting it like this works:
results = from p in theDocuments
join cust in outletService.GetAllCustomers() on p.customer_id equals cust.id
select new DocumentModel()
{
customer_name = cust.name,
document_id = p.document_id,
document_type = p.document_type,
franchisee_id = p.franchisee_id,
customer_id = p.customer_id,
address = p.address
};
I understand that this cannot be converted to it's relevant SQL, however, I am not sure what the second query is doing differently in it's execution in order for it to work, does it execute the GetAllCustomers() before doing anything else? How is it working differently internally?
How could I rewrite the first query so that it executes correctly?
Thanks,
James.
**This is what I ended up with **
results = theDocuments.Join(
outletService.GetAllCustomers(), docs => docs.customer_id, customers => customers.id, (doc, cust) => new DocumentModel()
{
document_id = doc.document_id,
document_type = doc.document_type,
franchisee_id = doc.franchisee_id,
customer_id = doc.customer_id,
address = doc.address,
area_id = doc.area_id,
customer_name = cust.name
});
The first one try to translate your method into a SQL method, the second create a join in the query. In my opinion the correct way is using join :)
I was a problem. I found a solution. That might be help you.
dynamic user = new
{
Name = "",
Surname = ""
};
dynamic userModel = new
{
Name = "",
Surname = "",
FullName = ""
};
var query = db.User.AsNoTracking();
query = query.Select(x => new userModel
{
Name = x.Name,
Surname = x.SurName,
FullName = $"{x.Name}{x.SurName}",
}).ToList();
If you try to execute this query. You will take a crash. Linq doesnt support
FullName = $"{x.Name}{x.SurName}"
You have to change this line to
FullName = x.Name + " " + x.SurName

linq orderby query inside of an if statement

I'm trying to do some code which basically says do search, if orderByLastName is true order by lastname and if false order by first name.
if(orderByLastName)
{
var query = from p in db.People
orderby p.LastName
select new {Name = p.FirstName + " " + p.LastName}
}
else
{
var query = from p in db.People
orderby p.FirstName
select new {Name = p.FirstName + " " + p.LastName}
}
The above code is my attempt at accomplishing this. It doesn't work because query does not exist outside of the if context which is clearly bad! And also I'm pretty sure the code violates the dry principle. Can someone see a nicer way of doing this? Thanks.
You can run as many queries on your IQueryable collection as you want, all of them will be executed right in place where you will make first cast of conversion to IEnumerable.
var query = db.People;
if(orderByLastName)
{
query = query.OrderBy(t=>t.LastName)
}
else
{
query = query.OrderBy(t=>t.FirstName)
}
var result = query.Select(t=> new {Name = t.FirstName + " " + t.LastName});
This is another solution :
Func<PeopleType, string> orderby;
if(orderByLastName)
orderby = t => t.LastName;
else
orderby = t => t.FirstName;
var result = db.People.OrderBy(orderby).Select(t => new { Name = t.FirstName + " " + t.LastName });

Perform group and join using LINQ

Does anyone have any suggestions about how I might do this using just LINQ?
var statements = db.vwOutstandingStatements.ToList();
var amounts = (from s in db.vwOutstandingStatements
group s by s.Id into v
select new
{
Id = v.Key,
amount = v.Sum(a => a.Amount)
}).ToList();
List<vmVendorStatements> statementsToProcess = new List<vmVendorStatements>();
foreach (var amount in amounts)
{
var statement = statements.Find(s => s.Id == amount.Id);
statementsToProcess.Add(new vmVendorStatements()
{
Id = statement.Id,
PropertyAddress = statement.PropertyNumber + " " + statement.PropertyStreet + " " + statement.PropertyTown,
StatementDate = statement.StatementDate.ToLongDateString(),
Amount = amount.amount.ToString()
});
}
Statements is from a sql view via EF5. I run the LINQ to get the data grouped by the sum of the amounts in the returned view and then join it back to show some of the detail from the returned view along with the sums amounts. StatementsToView is my view model to get the data into an MVC view.
I'm sure it could be done in SQL, and I might do that in any case, but there also seems as though there must be a neater solution to the above too.
Thanks,
Jason.
You can just grab out the first item in the group rather than re-querying just to find the first item:
var statementsToProcess =
(from s in db.vwOutstandingStatements
group s by s.Id into v
let first = v.First()
select new vmVendorStatements()
{
Id = v.Key,
amount = v.Sum(a => a.Amount),
PropertyAddress = first.PropertyNumber + " " + first.PropertyStreet + " " + first.PropertyTown,
StatementDate = first.StatementDate.ToLongDateString(),
}).ToList();

Categories