Add items to list from IEnumerable using LinQ - c#

I'm adding new items to a list from a IEnumerable (query.Roles).
var query = GetRoles();
var vm = new CreateUserViewModel();
vm.Role = new List<CreateUserViewModel.Item>();
foreach (var Role in query.Roles)
{
vm.Role.Add(new CreateUserViewModel.Item
{
Label = Role.Label,
RoleNumber = Role.RoleNumer
});
}
How i can do the 'Add' to the list with Linq?

AddRange should do it for you:
vm.Role.AddRange(query.Roles.Select(r => new CreateUserViewModel.Item
{
Label = r.Label,
RoleNumber = r.RoleNumer
}));
AddRange takes an IEnumerable parameter and adds each item to the collection.

vm.Role = query
.Roles
.Select(r=>new CreatUserViewModel
.Item{Label = r.Label,
RoleNumber = r.RoleNumber})
.ToList();

Related

C# List.Add overwrites previous objects

I am trying to create a simple list of objects, but somehow on every foreach loop the previous records are overwritten by the new one loop the previous record is overwritten by the new record. So if there are 6 entries in realData, the list will have 6x the last record.
Do I somehow recreate the List instead of adding to it? Is there another alternative that I have overlooked to create a List?
My code is
public async Task<IActionResult> OrderOverview()
{
var itemList = new List<OrderItemVM>();
var realData = await _context.OrderItem.ToListAsync();
var orderItemVM = new OrderItemVM();
foreach (var item in realData)
{
orderItemVM.Id = item.Id;
orderItemVM.OrderId = item.OrderId;
orderItemVM.OrderName = _context.Order.Find(item.OrderId).OrderName;
orderItemVM.ItemName = item.ItemName;
itemList.Add(orderItemVM);
}
return View(itemList);
}
You are modifying the previously added objects instead of adding a new one. You should do this.
foreach (var item in realData)
{
OrderItemVM orderItemVM = new OrderItemVM ();
orderItemVM.Id = item.Id;
orderItemVM.OrderId = item.OrderId;
orderItemVM.OrderName = _context.Order.Find(item.OrderId).OrderName;
orderItemVM.ItemName = item.ItemName;
itemList.Add(orderItemVM);
}
So, basically on each iteration you create a new empty object and then assign that values and add that in List.
It happens because you are inserting the same reference of orderItemVM to itemList.
Also, you can set a default size for itemList and boost performance.
var realData = await _context.OrderItem.ToListAsync();
var itemList = new List<OrderItemVM>(realData.Count);
And for this task, you can use LINQ:
public async Task<IActionResult> OrderOverview()
{
var realData = await _context.OrderItem.ToListAsync();
var itemList = realData.Select(item => new OrderItemVM
{
Id = item.Id,
OrderId = item.OrderId,
OrderName = _context.Order.Find(item.OrderId).OrderName,
ItemName = item.ItemNam,
}).ToList();
return View(itemList);
}
Thanks to Lasse V. Karlsen I discovered the error. I moved the line var OrderItemVM = new OrderItemVM in the Foreach-loop. That solved it.

Find all MongoDB documents from a list of ObjectIDs

I am trying to find all documents from a MongoDB database, which has the ObjectID from my list of IDs with C#. Here's what I'm trying:
public IEnumerable<Product> GetFromIDs(List<string> productIDs)
{
var client = new MongoClient(new MongoUrl("mongodb://localhost:27017"));
var db = client.GetDatabase("Database");
var products = db.GetCollection<Product>("Products")
.Find(x => x._id == productIDs)
.ToEnumerable();
return products;
}
productIDs is simply a list of ObjectIDs from the MongoDB database. Obviously trying to find by a list of IDs doesn't work that way, as it takes a single parameter.
How do I .Find() all the documents from my list of product IDs?
This is the strongly-typed way.
public IEnumerable<Product> GetFromIDs(List<string> productIDs)
{
var client = new MongoClient(new MongoUrl("mongodb://localhost:27017"));
var db = client.GetDatabase("Database");
var productsCollection = db.GetCollection<Product>("Products");
var productObjectIDs = productIDs.Select(id => new ObjectId(id));
var filter = Builders<Product>.Filter
.In(p => p.Id, productObjectIDs);
var products = productsCollection
.Find(filter)
.ToEnumerable();
return products;
}
I figured out a pretty hacky solution. Not one of my proudest moments to be honest:
ObjectId[] allIDs = new ObjectId[productIDs.Count];
for(var i = 0; i < productIDs.Count; i++)
{
allIDs[i] = new ObjectId(productIDs[i]);
}
var filter = new BsonDocument("_id", new BsonDocument("$in", new BsonArray(allIDs)));
var products = db.GetCollection<Product>("Products").Find(filter).ToEnumerable();
But hey, it works.

How to simplify the code Using LINQ

I need to know how to implement the below logic to get the list of items with the help of LINQ without using foreach. Also, I need to exclude those matching Items from item List after adding the item into new list.
Code
List<StockResult> Stockres = new List<StockResult>();
foreach (var stkitms in item)
{
if (Db.Stk.Any(a => a.INo == stkitms.ItemNum))
{
StockResult ss = new StockResult();
ss.ItemNumber = stkitms.ItemNum;
ss.FileName = stkitms.FileName;
Stockres.Add(ss);
}
}
Any solution to this will be appreciated.
You could try this one:
List<StockResult> Stockres = item.Where(x=>Db.Stk.Any(a => a.INo == x.ItemNum))
Select(x=> new StockResult()
{
ItemNumber = x.ItemNum,
FileName = x.FileName
}).ToList();

ASP.NET DropDown returning value of SelectedText instead of SelectedValue

What am I missing?
I am constructing dropdowns, like this, from code-behind:
ListItemCollection oL = new ListItemCollection();
foreach (var item in edata)
{
ListItem oListItem = new ListItem();
oListItem.Text = item.StatusName; //"StatusName"
oListItem.Value = item.Id.ToString(); // "StatusId"
if(item.Id == statusid)
{
oListItem.Selected = true;
}
oL.Add(oListItem);
}
But when I try to pick SelectedItem.Value like this, it should return StatusId but it is returning StatusName. What am I missing?
EventStatusDropDownList1.SelectedItem.Value
What does edata stand for here? If it is a DataTable or generic List, you can use DataSource and DataBind members. See the code below:
var edata = SomeMethodReturnngDataTable();
EventStatusDropDownList1.DataSource = edata;
EventStatusDropDownList1.DataTextField = "StatusName";
EventStatusDropDownList1.DataValueField = "StatusId";
EventStatusDropDownList1.DataBind();
Now you can use EventStatusDropDownList1.SelectedItem.Value to get the ID.

hashtable keys from multiple objects in linq

Hashtable mainhash = new Hashtable();
testdata td = new testdata() { value = "td" };
td.hash.Add("1", "tdvalue1");
td.hash.Add("2", "tdvalue2");
td.hash.Add("3", "tdvalue3");
td.hash.Add("4", "tdvalue4");
td.hash.Add("5", "tdvalue5");
testdata td1 = new testdata() { value = "td1" };
td1.hash.Add("1", "td1value1");
td1.hash.Add("2", "td1value2");
td1.hash.Add("3", "td1value3");
td1.hash.Add("4", "td1value4");
td1.hash.Add("5", "td1value5");
testdata td2 = new testdata() { value = "td2" };
td2.hash.Add("1", "td2value1");
td2.hash.Add("2", "td2value2");
td2.hash.Add("3", "td2value3");
td2.hash.Add("4", "td2value4");
td2.hash.Add("5", "td2value5");
testdata td3 = new testdata() { value = "td3" };
td3.hash.Add("1", "td3value1");
td3.hash.Add("2", "td3value2");
td3.hash.Add("3", "td3value3");
td3.hash.Add("4", "td3value4");
td3.hash.Add("5", "td3value5");
testdata td4 = new testdata() { value = "td4" };
td4.hash.Add("1", "td4value1");
td4.hash.Add("2", "td4value2");
td4.hash.Add("3", "td4value3");
td4.hash.Add("4", "td4value4");
td4.hash.Add("5", "td4value5");
mainhash.Add(1, td);
mainhash.Add(2, td1);
mainhash.Add(3, td2);
mainhash.Add(4, td3);
mainhash.Add(5, td4);
how to select all the keys using SelectMany by Linq into one list??
what i need to do in this??
var values = mainhash.Values.Cast<testdata>().Select(x => x.hash)
.SelectMany(x=> x.Keys);
what is wrong in this??
It doesn't know the type to use from Hashtable.Keys.
Try:
var values = mainhash.Values.Cast<testdata>().Select(x => x.hash)
.SelectMany(x => x.Keys.Cast<string>());
But better: use Dictionary<TKey,TValue> instead of Hashtable.
try below query -
var values = mainhash.Values.Cast<testdata>().SelectMany(x => x.hash.Keys.Cast<string>());
But, use dictionary instead of hashtable. It actually reduce the overhead of casting the objects.
hope above code helps you !!

Categories