Concatenate two fields in select list (C#) - c#

I use a viewbag to create a select list and I want to Show two fields concatenated together. However, it is crashing on my view. Here is the viewbag code:
ViewBag.PackageId = new SelectList(db.Packages.Where(p => p.status == "A"), "u_package_id", "u_package_id" + "'-'" + "package_nme");

This should work
ViewBag.PackageId = db.Packages.Where(p => p.status == "A")
.Select(p => new SelectListItem
{
Text = p.u_package_id + "-" + p.package_nme,
Value = p.u_package_id
};

The 2nd and 3rd parameters of the SelectList constructor are strings that must match the names of properties in your model (in your case your don't have a property named "u_package_id-package_nme" hence the error).
In the controller, generate a collection of SelectListItem
ViewBag.PackageList = db.Packages.Where(p => p.status == "A").Select(p => new SelectListItem()
{
Value = p.u_package_id, // may need .ToString() depending on the property type
Text = string.Format("{0}-{1}", p.u_package_id, p.package_nme)
}
Side note: Suggest you name your properties to reflect what they are (i.e. its a collection of items, not an ID so PackageList, not PackageId) and this would be necessary anyway if the model your binding to contains a property named PackageId

Thanks to deramko, I have my answer. He was 99% of the way there. Here is the final code:
ViewBag.PackageId = db.Packages.Where(p => p.status == "A")
.Select(p => new SelectListItem
{
Text = p.u_package_id + "-" + p.package_nme,
Value = p.u_package_id.ToString()
});

Related

How to get value from Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable in mvc controller

I know the title is somewhat complicate but let I clear the title by explaining the problem.
As per image I want to filter product name in search textbox. For ex: In search textbox if I enter the oil that in datatable whole data want to show which product name is oil.
For filter I used linq query, here is my code,
var dataList = (from x in query
select new
{
PartName = _Db.Part.Where(z => z.Id == x.Select(p => p.PartId).FirstOrDefault()).Select(p => p.Name),
ManufacturerName = _Db.Manufacture.Where(z => z.Id == x.Select(p => p.ManufacturerId).FirstOrDefault()).Select(p => p.name),
CategoryName = _Db.Category.Where(z => z.Id == x.Select(p => p.CategoryId).FirstOrDefault()).Select(p => p.Name),
Pcs = x.Sum(o =>o.Pcs) -
(from m in _Db.MaterialRecord
join s in _Db.ServiceJob on m.ServiceJobId equals s.Id
where m.pid == x.Select(p => p.PartId).FirstOrDefault()
select m).Sum(z => z.Qty),
Weight = _Db.Purchase.Where(p => p.Weight == x.Select(s => s.Weight).FirstOrDefault()).Select(a => a.Weight).FirstOrDefault(),
WeightType = x.Select(p => p.WeightTypeId).FirstOrDefault() > 0 ?((WeightType)x.Select(p => p.WeightTypeId).FirstOrDefault()).ToString() :"",
}).ToList();
//Search
if (!string.IsNullOrEmpty(searchValue))
dataList = dataList.Where(m => m.CategoryName.Contains(searchValue.ToString().ToLower())).ToList();
//Returning Json Data
return Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = data });
As per code I am getting whole data in datalist variable. Now, when I search any product in searchbox at that time the condition of search will true and after that the datalist value will be null[as shown by debug the code].
So, hence from that datatable shows null data.
For understanding that why this happening I add the tostring() in datalist query of category line i.e.
CategoryName = _Db.Category.Where(z => z.Id == x.Select(p => p.CategoryId).FirstOrDefault()).Select(p => p.Name).toString(),
After adding toString() in this line it shows this line Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable. But I want the result value of this line. For more clear lets see the another image
That oil result value I want in search condition line i.e.
dataList = dataList.Where(m => m.CategoryName.Contains(searchValue.ToString().ToLower())).ToList();
but right now in it is showing this line Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable in the place of result value.
First thing you should know is ToString() by its default implementation returns fully-qualified name of the object when applied to collection objects, in this case returns Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable<string> which is a reference type that doesn't override that method.
Let's evaluate this expression first:
CategoryName = _Db.Category.Where(z => z.Id == x.Select(p => p.CategoryId).FirstOrDefault())
.Select(p => p.Name),
Assumed that Category has DbSet<Category> type, the Select() extension method used in code above returns EntityQueryable<string> which contains result set collection from executed SQL statement provided by LINQ-to-Entities query. If you want to pull single string value from that collection, you must use one of the First(), Single(), FirstOrDefault() or SingleOrDefault() extension methods.
Hence, you should add extension method as mentioned above to return a string value instead of a collection:
var dataList = (from x in query
select new {
// other properties
CategoryName = _Db.Category.Where(z => z.Id == x.Select(p => p.CategoryId).FirstOrDefault())
.Select(p => p.Name).SingleOrDefault(),
// other properties
}).ToList();
Then you can use Contains against a substring (searchValue) because CategoryName has string type:
dataList = dataList.Where(m => m.CategoryName.Contains(searchValue.ToString().ToLower())).ToList();
Reference:
Entity Framework/Core and LINQ to Entities Query Methods (Operators)

Linq - selection item from ListView

How could I select all information about selected item, not only first column but all ?
For the first column I just need :
ListView.Items.AddRange(ListData
.Where(i => string.IsNullOrEmpty(searchBox.Text) || i.ID.StartsWith(searchBox.Text))
.Select(c => new ListViewItem(c.ID))
.ToArray());
Lets say that next columns are : Name, LastName
I know that I have to use Linq segment which looks like :
(...).Select(c => { })
Thanks in advance!
You can use the ListViewItem ctor that accept an array of string (where elements after the first are the subitems)
Assuming your class has the properties LastName and Name
ListView.Items.AddRange(ListData.Where(i =>
string.IsNullOrEmpty(searchBox.Text)
|| i.ID.StartsWith(searchBox.Text))
.Select(c => new ListViewItem // this part
(
new string[]{c.ID, c.Name, c.LastName}
)).ToArray());
If the creation of a single ListViewItem get more complicated, consider using a funcion:
ListView.Items.AddRange(ListData.Where(i =>
string.IsNullOrEmpty(searchBox.Text)
|| i.ID.StartsWith(searchBox.Text))
.Select(c => CreateListViewItemFromElement(c)).ToArray());
private ListViewItem CreateListViewItemFromElement(MyClass element)
{
// handle the element to create a "complete" ListViewItem with subitems
ListViewItem item = new ListViewItem(c.ID);
....
return item;
}
(actually, I would use the latter in every case, it's much more readable to me)
Just init all properties that you need in .Select() method line this:
ListView.Items.AddRange(ListData.Where(i =>
string.IsNullOrEmpty(searchBox.Text)
|| i.ID.StartsWith(searchBox.Text))
.Select(c => new ListViewItem // this part
{
Name = c.ID.ToString(),
Text = c.Name + " " + c.LastName
}).ToArray());
Maby you want to fill different properties, so fill freee to change this part as you want.
Well, the ListViewItem class has 22 (!) constructor overloads, so you can use any of them that supports passing string[] items, for instance this one:
.Select(c => new ListViewItem(new string[] { c.ID, c.Name, c.LastName }))

MVC/C#: DropDownListFor not selecting 'selected' item

ok, I have a situation where I need to have multiple DDLs of 'BayTypes' that use the same dictionary, which isn't a problem. One DDL for each of 'n' BayOptions. I'm passing a dictionary to my view as 'BayTypes' like this:
(Controller)
var bayTypes = _bayTypeRepository.GetBayTypes().ToList();
property.BayTypes = bayTypes.ToDictionary(g => g.Name, g => g.BayTypeGuid.ToString());
(View)
var overrideValue = item.BayTypeOverride ? item.BayTypeOverrideValue.BayTypeGuid.ToString() : string.Empty;
var result = (from x in Model.BayTypes
select new SelectListItem()
{
Text = x.Key,
Value = x.Value,
Selected = x.Value == overrideValue <-- ***this is working***
});
if (item.BayTypeOverride == true)
{
#Html.DropDownListFor(x => x.BayTypes, result, new { #Name = "BayOptionsToSubmit[" + aCounter + "].BayTypeOverrideValue" })
}
else
{
#Html.DropDownListFor(x => x.BayTypes, result, new { #Name = "BayOptionsToSubmit[" + aCounter + "].BayTypeOverrideValue", #style = "display:none;" })
}
The correct item IS getting selected in the 'result' object. If I step through, and watch 'result', I can see that 'Selected = true' for the right one... but it's not selecting in the DDLFor when it renders...
What am I missing?
Ultimately, what determines the "selected" item in a drop down is ModelState, not the SelectListItem.Selected property. ModelState is composed from the following sources: Request, ViewData, ViewBag, and finally Model.
Check the values of Request["BayTypes"], ViewData["BayTypes"], ViewBag.BayTypes, and Model.BayTypes. If any of those has a different value from what you're expecting to be selected, that's your problem, particularly if the value is not even in the ballpark.
For example, a common cause of this is developers storing their actual select list choices in something like ViewBag.Foo and then trying to apply that to a dropdown bound to Model.Foo. The select list itself at that point becomes the selected item in ModelState, rather than the one particular value you selected.
Solved it... Changed to a .DropDownList (no 'For') and passed in the 'name' as the 'result' var created earlier. Works.
var overrideValue = item.BayTypeOverride ? item.BayTypeOverrideValue.BayTypeGuid.ToString() : string.Empty;
var result = (from x in Model.BayTypes
select new SelectListItem()
{
Text = x.Key,
Value = x.Value,
Selected = x.Value == overrideValue
});
if (item.BayTypeOverride)
{
#Html.DropDownList("result", result, htmlAttributes: new { #Name = "BayOptionsToSubmit[" + aCounter + "].BayTypeOverrideValue" })
}
else
{
#Html.DropDownList("result", result, htmlAttributes: new { #Name = "BayOptionsToSubmit[" + aCounter + "].BayTypeOverrideValue", #style = "display:none;" })
}

Convert IDictionary<Guid,string> to the IEnumerable<SelectListItem>

How i can convert IDictionary<Guid,string> to the IEnumerable<SelectListItem>?
I want to use string as SelectListItem.
If you want to use the guid as the value, you can use
dictionary.Select(x => new SelectListItem { Text = x.Value, Value = x.Key })
Well you could just use
dictionary.Values().Select(x => new SelectedListItem { Text = x })
Just be aware that it may not be in a useful order: Dictionary<,> is inherently unordered (or rather, the order may change and shouldn't be relied on).
Something like this should do what you want:
var selectList = dictionary
.OrderBy(kvp => kvp.Value) // Order the Select List by the dictionary value
.Select(kvp => new SelectListItem
{
Selected = kvp.Key == model.SelectedGuid, // optional but would allow you to maintain the selection when re-displaying the view
Text = kvp.Value,
Value = kvp.Key
})
.ToList();
Using LINQ, you could do something like,
var theSelectList = from dictItem in dict
select new SelectListItem()
{
Text = dictItem.Value,
Value = dictItem.Key.ToString()
};

Update the selected dropdownlist value base on value from another linq query

I use the following code to get the LOV for dropdownlist and setting a selected value as well:
ViewData["dropDown_Color"] = correspondingDropDownValue
.Select(j =>
new SelectListItem {
Text = j.ListOfValue,
Value = j.ListOfValue,
Selected = j.ListOfValue
== x.DefaultValue
})
.ToList();
Now that I have a dropdownlist in my ViewData, I want to update the selected value of this ViewData["dropDown_Color"] base on the following query
var userPref = from m in db.UserColorPref
where m.UserID.Equals(userSessionID)
select m;
The value to be updated can be access by userPref.color. May I know how to achieve my objective?
Use this
List<SelectListItem> selectlist = ViewData["dropDown_Color"] as List<SelectListItem>;
selectlist.ForEach(x =>
{
x.Selected = x.Value == userPref.color;
});
You can achieve it as follows:
ViewData["dropDown_Color"] = new SelectList(YourSelectList, "Value", "Text", selectedValue);

Categories

Resources