Viewbag assign value for each iteration results in error - asp.net-mvc

I am trying to dynamically set a value for each iteration of
int index = 0;
foreach (var item in model.ResponseRetest)
{
var result = _pointService.GetBuildings(item.ID).Select(x => new SelectListItem { Text = x, Value = x }).ToList();
ViewBag.Company[index] = result;
index++;
}
Even though result does have a value, I am getting the following error:
Message "Cannot perform runtime binding on a null reference"

Using ViewBag this way is not recommended as it creates overhead in unboxing the data with every iteration (in this case, Company). The error is likely happening on the first iteration because you're applying indexing on non-existent property Company.
List<List<datatype>> companyResults = new List<List<datatype>>();
foreach (var item in model.ResponseRetest)
{
var result = _pointService.GetBuildings(item.ID).Select(x => new SelectListItem { Text = x, Value = x }).ToList();
companyResults.Add(result);
}
ViewBag.Company = companyResults;

Related

How do I remove the foreach from this linq code?

I'm fairly new at MVC and linq and viewmodels in particular. I managed to get a create and index views to work. The "insert" wasn't as hard as the "list".
I have this linq query:
public ActionResult Index()
{
List<BlendElVM> BEVM = new List<BlendElVM>();
var list = (from Blend in db.blends
join BlendEl in db.blendEl on Blend.ID equals BlendEl.ID
select new
{
Blend.ID, Blend.Title, Blend.TransDt, BlendEl.Comment
}).ToList();
foreach (var item in list)
{
BlendElVM o = new BlendElVM(); // ViewModel
o.Comment = item.Comment;
o.Title = item.Title;
o.TransDt = item.TransDt;
o.ID = item.ID;
BEVM.Add(o);
}
return View(BEVM);
}
What I'm not sure about is the "foreach" section. When I'm running in debug, the "list" shows up fine, but if I comment out the "foreach" I get an error - ie not expecting the model. What does the foreach do? It has to do with the database, but I don't understand the where it is using the "o" and setting the columns. I thought it would all be in one linq query. Is it possible to combine the two and eliminate the "foreach"?
var BEVM = (from blend in db.blends
join BlendEl in db.blendEl on Blend.ID equals BlendEl.ID
select new BlendELVM
{
ID = blend.ID,
Title = blend.Title,
TransDT = blend.TransDt,
comment = blendEl.Comment
}).ToList();
I believe that the foreach is needed in order to read every element in the object so in this case you have:
BlendElVM o = new BlendElVM();
So you're creating and object named " o " of the type BlendELVM and this object contains all the attributes that you declared before which are: ID, Title, TransDT, etc
When you put:
foreach (var item in list)
{
BlendElVM o = new BlendElVM(); // ViewModel
o.Comment = item.Comment;
o.Title = item.Title;
o.TransDt = item.TransDt;
o.ID = item.ID;
BEVM.Add(o);
}
You're assigning to the new object o the item that you're reading in the list and in the end adding it to the BVEM list and answering if you can combine them i will say no because at first you're declaring the query and then you're reading the items on the list and assining them to the BEVM list

Is there any way get datarow from datatable without using foreach

Controller
foreach (DataRow temp in act.Rows)
{
_oResolutionModel.activityNo = temp["ActivityID"].ToString();
_oResolutionModel.assignTechnician = temp["TechNo"].ToString();
_oResolutionModel.recommendation = temp["RECOMMENDATION"].ToString();
_oResolutionModel.jobStart = (DateTime)temp["JobStart"];
_oResolutionModel.jobEnd = (DateTime)temp["JobEnd"];
_oResolutionFacade.setResolutionID(_oResolutionModel.activityNo);
DataTable res = _oResolutionFacade.getResolution(_oAppSetting.ConnectionString);
foreach (DataRow x in res.Rows)
{
_oResolutionModel.solution = x["Resolution"].ToString();
_oResolutionModel.remarks = x["Remarks"].ToString();
_oResolutionList.Add(_oResolutionModel);
break;
}
_oResolutionList.Add(_oResolutionModel);
break;
}
In here my _oResolutionList count = 1, meaning there's two data in it and it duplicated the first data. I want to have only 1 data in my _oResolutionList. Do I need to add some code in my inner Foreach or should I change something on it.?
Or You can suggest me how to delete the second data entry.?
Instead of using a foreach loop. You can also check the nullity first and then assign.
You can also do :
_oResolutionFacade.setResolutionID(_oResolutionModel.activityNo);
DataTable res = _oResolutionFacade.getResolution(_oAppSetting.ConnectionString);
_oResolutionModel.solution = res.Rows[0]["Resolution"].ToString() ?? string.Empty; //To make sure that if it is null it will assign to an empty string
_oResolutionModel.remarks = res.Rows[0]["Remarks"].ToString()?? string.Empty;
You have many solutions to deal with that.
Hope it will help you

there's something wrong with my controller codes

My Controller
public ActionResult Index()
{
TechnicianFacade _oTechFacade = new TechnicianFacade();
Maintenance_.Models.IndexModel _oTechModel = new Maintenance_.Models.IndexModel();
IList<Maintenance_.Models.IndexModel> _otechList = new List<Maintenance_.Models.IndexModel>();
var tech = _oTechFacade.getTechnicians("", _oAppSetting.ConnectionString).ToArray();
foreach (var test in tech)
{
string fName = test.GetType().GetProperty("FIRSTNAME").GetValue(test, null).ToString();
_oTechModel.firstName = fName;
_otechList.Add(_oTechModel); <===
}
_oTechModel.fNameList = _otechList;
return View("Index", _oTechModel);
}
In my controller: index, can get all data object from my database. But if I have more than one data object in my database the: _otechList.Add(_otechModel) will overwrite the first entry with the newly added data, like for example lets just say we have 2 object data: (FIRST loop of foreach) _otechList.Add(_oTechModel) has a data of "FIRSTNAME" = "GEM" where count = 0, (SECOND loop of foreach) _otechList.Add(_oTechModel) has a data of "FIRSTNAME" = "DIAMOND" where count = 1, this time the value of count[0] became "FIRSTNAME" = "DIAMOND" as well. Is there something missing in my code or there's something wrong on it?
It will replace because same object value is changed, you need to instantiate object inside foreach loop.
Maintenance_.Models.IndexModel _oTechModel = new Maintenance_.Models.IndexModel();
like this:
foreach (var test in tech)
{
string fName = test.GetType().GetProperty("FIRSTNAME").GetValue(test, null).ToString();
Maintenance_.Models.IndexModel _oTechModel = new Maintenance_.Models.IndexModel();
_oTechModel.firstName = fName;
_otechList.Add(_oTechModel);
}
your object is global so every time same object is added in the list, instantiate it inside foreach loop so that every time new object is added in the list.

linq to entities - updating tables with new values not working

The code below is updating the correct values into the OBJECT_TYPES table, but the OBJECT_ITEMS table is being overwritten but I am not sure why. Can anyone help?
var templateId = Request["id"].AsInt();
var dbcontext = new STDEntities1();
var query = dbcontext.OBJECT_TYPES.Where(o => o.ID == templateId);
var template = query.FirstOrDefault();
var newItem = new OBJECT_TYPES
{
CATEGORY_ID = template.CATEGORY_ID,
COMPANY_ID = template.COMPANY_ID,
OBJECT_NAME = "** Select A Name **",
HEIGHT = template.HEIGHT,
WIDTH = template.WIDTH,
TEMPLATE = template.ID
};
foreach (var field in template.OBJECT_ITEMS)
{
newItem.OBJECT_ITEMS.Add(field);
}
dbcontext.OBJECT_TYPES.Add(newItem);
dbcontext.SaveChanges();
this is happening because you are adding field which actually is an object that is being tracked by the dataContext/dbContext and even has an id. So the values are being overwritten.
Try creating the a new field OR try detaching the field from the context and then put the Id/Primary key to 0 and try inserting it again.

Issue With Showing Distinct fields using Linq

var getAllProducts = _productService.GetAllProducts();
if (productstest.Count > 0)
{
model.idproduct.Add(new SelectListItem()
{
Value = "0",
Text = _localizationService.GetResource("Common.All")
});
foreach (var m in getAllProducts)
model.idproduct.Add(new SelectListItem()
{
Value = m.Id.ToString(),
**Text = m.Size.Distinct().ToString(),**
Selected = model.Pid == m.Id
});
}
public virtual IList<Product> GetAllProducts(bool showHidden = false)
{
var query = from p in _productRepository.Table
orderby p.Name
where (showHidden || p.Published) &&
!p.Deleted
select p;
var products = query.ToList();
return products;
}
The issue is even i tried to populate the select list with distinct size using: Text = m.Size.Distinct().ToString(), but it shows the duplicate for instance 100 products are of size 33 cm , the list will populate the dropdownlist in the view with 33cm occuring 100 times , I dont want to show 100 times , just want to show 1 time, Can any one assist me with this issue ?
Presumably you are only trying to show one product of each different size... if so initialising your getAllProducts variable like so will do the trick:
var getAllProducts = _productService.GetAllProducts().GroupBy(p => p.Size).Select(g => g.First());

Resources