0

I have a HTTP GET Web API method that returns a list and got this error when it was called concurrently by a process it returned this error: Destination array was not long enough. Check destIndex and length, and the array's lower bounds.

    public List<ItemList> GetAllItems(int Id)
    {
        List<ItemList> items = new List<ItemList>();
        var itemsToPutIntoNewList = _unitOfWork.ItemRepo.All.Where(x => x.Id== Id).ToList();

        foreach (var item in itemsToPutIntoNewList )
        {
            items.Add(new ItemList
            {
                ItemId= item.Id,
                Name = item.Name,
                Color = item.Feature.Color,
                DateReteived = Datetime.Now
            });
        }

        return items;
    }

What's the best way to handle this potential error?

user3266638
  • 429
  • 8
  • 25
  • There are many questions with the same issue here. Check them first. https://stackoverflow.com/questions/50240932/what-could-cause-destination-array-was-not-long-enough-during-list-add-in-a-si and https://stackoverflow.com/questions/10362023/destination-array-not-long-enough and others – Sully Nov 21 '19 at 04:11

1 Answers1

1

First, check that ItemRepo is returning IQueryable<Item> and not something like IEnumerable<Item>. Also ensure that you aren't dealing with any static references such as _unitOfWork. Normally a Unit of Work pattern should be scoped to either the request or the specific method. Provided you are dealing with IQueryable and the UoW is lifetime scoped to the request at worst then leverage EF to populate your result list rather than fetching entities and adding them one by one to the list:

var dateRetrieved = DateTime.Now;
var items = _unitofWork.ItemRepo.All.Where(x => x.Id == Id)
   .Select(x => new ItemList
   {
       ItemId= item.Id,
       Name = item.Name,
       Color = item.Feature.Color,
       DateReteived = dateRetrieved
   }).ToList();
return items;

Barring that, keep it simple and work out from there:

using (var context = new YourDbContextHere())
{
    var dateRetrieved = DateTime.Now;
    var items = context.Items.Where(x => x.Id == Id)
       .Select(x => new ItemList
       {
           ItemId= item.Id,
           Name = item.Name,
           Color = item.Feature.Color,
           DateReteived = dateRetrieved
       }).ToList();
    return items;
}

Without knowing what your repo does, I would also hazard a guess that you're hitting lazy load calls to the database with this code: Color = item.Feature.Color since your original code would need to eager load Feature with the Item to avoid an extra DbHit for every Item loaded.

Steve Py
  • 26,149
  • 3
  • 25
  • 43
  • On each request a controller instance will be created and the request method is called. So the injected UOW is scoped for the request. Creating the UOW inside the method results in an untestable method for **unit** test – Sir Rufo Nov 21 '19 at 05:07
  • Absolutely, hence the first statement to try with the existing patterns. If that does not work it helps to start by eliminating the obvious culprits, then re-factor back in best practice patterns to determine what broke it. It is unclear what _unitOfWork was actually scoped as and how it was initialized, nor how the OP implemented the repository pattern. I've seen people use a module level reference for a unit of work or DbContext only to find out later that their IoC had it scoped to Singleton. – Steve Py Nov 21 '19 at 07:38