【问题标题】:IEnumerable failed to set elementIEnumerable 未能设置元素
【发布时间】:2020-07-19 08:28:23
【问题描述】:

我有一个 ViewModel,它包含不同表中的不同元素,我倾向于通过查询分配给它。

我的问题是我不能用 IEnumerable (在下面的 GetAll() 中)执行此操作,它会一直返回我 nullRoomCode 但对于单个项目(在下面的 GetDeviceId() 中)然后它工作正常。

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;
}

【问题讨论】:

  • 首先,您可以使用foreach 来枚举元素,这是循环IEnumerable 的自然方式:foreach (var element in result) { int? deviceID = element.DeviceId; element.RoomCode = deviceRepository.GetRoomCode(deviceID); } 其次,检查每个元素的类型是否为@987654330 @(引用类型)而不是struct(值类型)。
  • 尝试调试您的代码并在GetRoomCode 函数中放置一个断点,以检查发生了什么以及返回什么。也许问题出在您的数据中,我们看不到,但您可以。
  • 我尝试了 foreach,现在它给了我“已经有一个打开的 DataReader 与此命令关联,必须先关闭”。我也进行了调试,我的 GetRoomCode 工作正常,但我无法将它分配给 IEnumerable RoomCode。我已经用一个项目对其进行了测试,我的函数 GetRoomCode() 工作正常。
  • 所以如果我理解得很好,GetDeviceID 中的代码可以正常工作,但GetAll 中的代码不行。我可以看到GetAll 使用字段/属性DeviceViewModel.DeviceId 的值调用GetRoomCode。函数 GetDeviceID 调用 GetRoomCode 时已将值作为参数,因此可能值得检查一下 deviceId 是否已正确填充到视图模型中。
  • 一切正常。我将我的视图模型项目设置为公开。我可以获取元素项的值,但我不能设置它。

标签: c# api ienumerable asp.net-mvc-viewmodel


【解决方案1】:

首先,您需要将查询具体化为本地内存中的集合。否则,ElementAt(i) 将在每次使用时查询数据库并返回某种临时对象,丢弃您所做的任何更改。

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.

然后您可以继续编写其余代码。

第二个(可能是可选的),为了清楚起见,我还建议使用foreach 来枚举元素。这是循环通过 IEnumerable 的 C# 惯用方式:

foreach (var element in result)
{
    int? deviceID = element.DeviceId;
    element.RoomCode = deviceRepository.GetRoomCode(deviceID);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-22
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 2019-09-18
    相关资源
    最近更新 更多