I have a ViewModel that contains different elements inside different tables that I tend to assign to it by query.
My problem is that I can't do this with IEnumerable
(in GetAll()
below), it keeps returning me null
for RoomCode
but for a single item (in GetDeviceId()
below) then it works fine.
public IEnumerable<DeviceViewModel> GetAll()
{
var result = deviceRepository.GetAll().Select(x => x.ToViewModel<DeviceViewModel>());
for(int i = 0; i < result.Count(); i++)
{
int? deviceID = result.ElementAt(i).DeviceId;
result.ElementAt(i).RoomCode = deviceRepository.GetRoomCode(deviceID);
}
return result;
}
public DeviceViewModel GetDeviceID(int deviceID)
{
var result = new DeviceViewModel();
var device = deviceRepository.Find(deviceID);
if (device != null)
{
result = device.ToViewModel<DeviceViewModel>();
result.RoomCode = deviceRepository.GetRoomCode(deviceID);
}
else
{
throw new BaseException(ErrorMessages.DEVICE_LIST_EMPTY);
}
return result;
}
public string GetRoomCode(int? deviceID)
{
string roomCode;
var roomDevice = dbContext.Set<RoomDevice>().FirstOrDefault(x => x.DeviceId == deviceID && x.IsActive == true);
if (roomDevice != null)
{
var room = dbContext.Set<Room>().Find(roomDevice.RoomId);
roomCode = room.RoomCode;
}
else
{
roomCode = "";
}
return roomCode;
}
First, you need to materialize the query to a collection in local memory. Otherwise, the ElementAt(i)
will query the db and give back some kind of temporary object each time it is used, discarding any change you do.
var result = deviceRepository.GetAll()
.Select(x => x.ToViewModel<DeviceViewModel>())
.ToList(); // this will materialize the query to a list in memory
// Now modifications of elements in the result IEnumerable will be persisted.
You can then go on with the rest of the code.
Second (and probably optional), I also recommend for clarity to use foreach
to enumerate the elements. That's the C# idiomatic way to loop through an IEnumerable
:
foreach (var element in result)
{
int? deviceID = element.DeviceId;
element.RoomCode = deviceRepository.GetRoomCode(deviceID);
}