Sorting SQL list by int - c#

i'm fairly new to MVC and entity framework and I was hoping someone would be able to help me.
I have a SQL database that has a column that contains ints. I want to pull these values out and put them into an html.dropdownlistfor
I was originally trying to do:
List<SelectListItem> List = dbAccess.KeywordCorrelationData.Select(
temp => new {
Value = temp.DefaultDestroyPeriod.ToString(),
Text = temp.DefaultDestroyPeriod.ToString()
}).OrderBy(temp => temp.Value).Distinct().ToList();
However this only sorted by the text value not numeric value.
I've since found a solution but it's a lot longer:
List<SelectListItem> List= new List<SelectListItem>();
List<int> tempIntList = dbAccess.KeywordCorrelationData.Select(temp => temp.DefaultDestroyPeriod).Distinct().ToList();
tempIntList.Sort();
foreach (int tempInt in tempIntList)
{
int wholeYears = (int)Math.Round((double)tempInt / 365, 0);
SelectListItem newItem = new SelectListItem()
{
Value = tempInt.ToString(),
Text = tempInt.ToString() + " days (approx. " + wholeYears.ToString() + (wholeYears == 1 ? " year)" : " years)")
};
List.Add(newItem);
}
return List;
I was wondering if there was a simpler way to do it than this? I've googled and searched on here but can't find anything like it.
Thanks

Assuming that DefaultDestroyPeriod is already of numeric type, just apply the ordering before you do the Select:
List<SelectListItem> List = dbAccess.KeywordCorrelationData
.OrderBy(kcd => kcd.DefaultDestroyPeriod)
.Select(kcd => new
{
Value = kcd.DefaultDestroyPeriod.ToString(),
Text = kcd.DefaultDestroyPeriod.ToString()
}).Distinct().ToList();

Related

Create selectlist with groups

I want to create selectlist with items from database grouped by RoomId.
var beds = service.GetApartmentBed(parentId)
.Select(x => new SelectListItem
{
Value = x.Id.ToString(),
Text = localizerBedsType[x.BedType.ToString()],
Group = new SelectListGroup { Name = x.RoomId.ToString()},
}).ToList();
AvailableBeds = new SelectList(beds,
nameof(SelectListItem.Value),
nameof(SelectListItem.Text),
BedId,
nameof(SelectListItem.Group.Name));
But when i want to test it in browser, its shows this error:
Image
This is value of item:
Image
but when i remove last parametr of AvailableBeds it's work well but I don't have groups.
Ok, ive done it. Ive need to change last line to "Group.Name"
AvailableBeds = new SelectList(beds,
nameof(SelectListItem.Value),
nameof(SelectListItem.Text),
BedId,
"Group.Name");

C# scan list against master list for missing items

I have a master list that has the values for tables of a database I know to be correct:
masterList: List<string>(){ "business", "customer", "location", "employee", etc}
And I've queried a new database that is supposed to be identical. My test will tell me if I have any errors in the scripts my team has made to make this new DB. tablesList is supposed to the be the return of my query:
tablesList: List<string>(){ "business", "customer", "location", "employee", etc}
So in practice they are supposed to be the same, but to test errors, I want to compare the tablesList against the masterList to make sure all needed tables are there. As a copy of this process, I'm also reversing the search, in case there are any extra tables that are not there on the masterList.
Question: How do I compare a list against a master list, and return items that don't match up?
I am using Visual Studio 2017 with c# .net Core 2.0.
Here is what I've been trying so far:
var errorsList = new List<string>();
tablesList = QuerySchemaForTables();
masterList = GrabMasterTableList();
foreach(var item in masterList)
errorsList.Add(tablesList.Where(x => x.Contains(item)));
But with this, I'm getting the error:
cannot convert from IEnumerable to string
You can get the two directions of errors using LINQ. No need for the loop:
var missingInMasterList = tableList.Where(x => !masterList.Contains(x)).ToList();
var missingInTableList = masterList.Where(x => !tableList.Contains(x)).ToList();
Are you looking for something like that;
var errorList = tableList.Where(x => !masterList.Contains(x));
You can capture the differences using .Except(), which is one of the IEnumerable set operations:
var missingTables = masterList.Except(tablesList);
var extraTables = tablesList.Except(masterList);
Then, to create your error message, you can join the items in these IEnumerables with a comma into a single string using string.Join():
var errorMessage = new StringBuilder();
if (missingTables.Any())
{
errorMessage.AppendLine("Missing Tables: " + string.Join(", ", missingTables));
}
if (extraTables.Any())
{
errorMessage.AppendLine("Extra Tables: " + string.Join(", ", extraTables));
}
Then you can output your results by checking the length of errorMessage to determine if any errors were encountered:
if (errorMessage.Length > 0)
{
Console.WriteLine(errorMessage.ToString());
}
else
{
Console.WriteLine("No extra or missing tables detected");
}
I think better to use is Except() as follows
var MasterList = new List<string> { "business", "customer", "location", "employee"};
var ChildList = new List<String> { "customer", "location", "employee" };
var filter = MasterList.Except(ChildList);
This will values those are not in ChildList.You can also do vice versa.
To find all items that are in the tablesList but not in the masterList use .Contains:
var errorsList = tableList.Where(x => !masterList.Contains(x));
But I recommend you use a HashSet<String> for masterList so search for an item in it will be in O(1) instead of O(n):
var masterCollection = new HashSet<String>(GrabMasterTableList());
var errorsList = tableList.Where(x => !masterCollection.Contains(x));
As for the problem with your code as you posted:
foreach(var item in masterList)
errorsList.Add(tablesList.Where(x => x.Contains(item))); // <-- error
As the error points out, Linq's .Where returns an IEnumerable<T> whereas .Add expects a single item of the type of the collection, which in this case is a single string. You could use .AddRange instead but I think a better use all together is what I wrote above.
Your code is presently trying to add an IEnumerable to a List.
If you want to add all the matches you should AddRange instead.
https://msdn.microsoft.com/en-us/library/z883w3dc(v=vs.110).aspx
var errorsList = new List<string>();
tablesList = QuerySchemaForTables();
masterList = GrabMasterTableList();
foreach(var item in masterList)
errorsList.AddRange(tablesList.Where(x => x.Contains(item)));

Can't get Value in a SelectListItem to be read as a string

I am trying to create a drop down list that combines the Responsibility and Level into one line within the list. However, I want them saving into their own columns within the SQl database so I have used the identity column from that table Responsibility_Key.
Here is my code:
public ActionResult Delegate(string Responsibility, string Responsibility_Key, string ADUserName, string Level, string submit)
{
var Dgates = cc_Db.Dim_Responsibility
.Select(s => new SelectListItem
{
Value = s.Responsibility_Key.ToString(),
Text = s.Responsibility + " - " + s.Level
});
ViewBag.Responsibility = new SelectList(Dgates, "Value", "Text");
return View();
}
I have tried multiple different ways of converting to a string as well as using .AsNumerable and IENumerable but with no success.
The error I keep getting is
"LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression."
Any help is greatly appreciated.
My guess (as you confirmed with your edit) is that you are using some kind of ORM, (e.g.) entity framework, and that it can't translate ToString() to SQL
First fetch an anonymous ienumerable, then tolist, e.g.
var Dgates = cc_Db.Dim_Responsibility.Select(new{
Value = s.Responsibility_Key,
Text = s.Responsibility + " - " + s.Level
}).ToList().Select(a => new SelectListItem
{
Value = a.Value.ToString(),
Text = a.Text
}).ToList();
Try calling ToList
var Dgates = cc_Db.Dim_Responsibility
.Select(s => new SelectListItem
{
Value = s.Responsibility_Key.ToString(),
Text = s.Responsibility + " - " + s.Level
}).ToList();
This will make Dgates a List<SelectListItem> which should satisfy new SelectList(Dgates, "Value", "Text");

SelectList Not Coming Back Sorted - C# MVC 3

All,
I am trying to sort my selectlist items and then prepend a default list item to the list, something like "Select an Item Below" and return that list via a method. I noticed that the list is not being sorted because it looks like, from what ReSharper is saying, I need to return the sorted result - so my method is not returning a sorted list.
Is there a way to do the sorting and prepending in the method?
Here is what I have:
public static IEnumerable<SelectListItem> GetBuildingClubs(List<BuildingClub> localClubs, List<BuildingClub> psfyClubs)
{
var buildingClubList = new List<SelectListItem>();
IEnumerable<BuildingClub> allBuildingClubs = localClubs.Union(psfyClubs);
foreach (BuildingClub b in allBuildingClubs)
{
buildingClubList.Add(new SelectListItem
{
Value = b.MasterCustomerId,
Text = b.NewBuildingClubName
});
}
//Sort list
buildingClubList.OrderBy(c => c.Text);
//Prepend to sorted list
buildingClubList.Insert(0, new SelectListItem
{
Value = "",
Text = "Select an Item Below"
});
return buildingClubList;
}
OrderBy doesn't modify the input list; it returns a new sorted sequence. You need to store that sequence and use it to build your list:
buildingClubList = buildingClubList.OrderBy(c => c.Text).ToList();
Alternatively, sort the items before you add them to the list:
IEnumerable<BuildingClub> allBuildingClubs = localClubs.Union(psfyClubs).OrderBy(b => b.NewBuildingClubName);

Lucene search not working

I have a function which searches some articles in the Sitecore content items and give me the value. So far I have build up my indexes and it is showing in my IndexViewer. But the return of the function is 0. I looked up this link: http://sitecoregadgets.blogspot.com/2009/11/working-with-lucene-search-index-in_25.html for more information.
protected IEnumerable<Item> ShowHomePageNews(int numOfArticles, string stringofCountries)
{
List<Item> items = new List<Item>();
Sitecore.Search.Index indx = SearchManager.GetIndex("newsArticles");
using (IndexSearchContext searchContext = indx.CreateSearchContext())
{
var db = Sitecore.Context.Database;
CombinedQuery query = new CombinedQuery();
QueryBase catQuery = new FieldQuery("countries", stringofCountries); //FieldName, FieldValue.
SearchHits results = searchContext.Search(catQuery); //Searching the content items by fields.
SearchResultCollection result = results.FetchResults(0, numOfArticles);
foreach (SearchResult i in result)
{
items = result
.Where(r => !r.Title.StartsWith("*"))
.Select(r => db.GetItem(new Sitecore.Data.ItemUri(r.Url).ToDataUri()))
.ToList();
//Lucene.Net.Documents.Field url = i.Document.GetField("_url");
//Sitecore.Data.ItemUri itemUri = new Sitecore.Data.ItemUri(url.StringValue());
//Sitecore.Data.Items.Item item = Sitecore.Context.Database.GetItem(itemUri.ToDataUri());
//items.Add(item);
}
}
return items;
}
Over here the result is 0. What I am doing wrond here?
This is the snapshot of what I am seeing in my IndexViewer:
EDIT:
I am passing a "NZ" in the 'catQuery' and I am getting the result back. Because in my index viewer I am seeing the Field Name = _name, which contains NZ in it. I got this part. However, I want my every field to be indexed. I am seeing only 3 fields in my IndexViewer: _url, _group & _name.
So your countries should be tokenized by the indexer. As a multilist, they will be tokenized by GUID. Searching for a single country by GUID with your code above should work. However, if you want to search for multiple countries, where any of the passed in countries can trigger a match, you need to structure your query differently.
CombinedQuery query = new CombinedQuery();
//apply other filters here to query if need be
//and country filter by creating a new clause (combinedquery) and "ORing" within it (QueryOccurance.Should)
CombinedQuery query3 = new CombinedQuery();
//here you would actually iterate over your country list
query3.Add(new FieldQuery("countries", country1GUID), QueryOccurance.Should);
query3.Add(new FieldQuery("countries", country2GUID), QueryOccurance.Should);
query.Add(query3, QueryOccurance.Must);

Categories

Resources