0

What is the time complexity of the .Find(id) method? Is it a bad idea to loop over a list of id's and use .Find()?

Also is it possible to 'find' multiple id's in the same query?

foreach (var id in idList)
{
    var task = _model.Tasks.Find(id);
    Save(task,task.id);
}

What is the best way of doing this?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Josh
  • 49
  • 8
  • 1
    This feels like a XY Problem (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Take a step back and explain your _underlying_ problem. – mjwills Feb 14 '18 at 12:49
  • 3
    `Find` performs a `SELECT * FROM TABLE WHERE ID = x`. If you want to bring all entities for a range of IDs, do a single query => `_model.Tasks.Where(x => idList.Contains(x.id))` – Camilo Terevinto Feb 14 '18 at 12:52
  • Why the tag? – jarlh Feb 14 '18 at 12:56
  • @jarlh Sometimes Entity Framework talks to SQL I guess... :P – Charleh Feb 14 '18 at 13:10
  • 1
    its very rare that you would want to find many different items which are not related in some form. So you would find them based on a shared commonality. Anyway you should not have a save inside of a for loop... this is probably your actual problem with regards to performance in this instance. – Seabizkit Feb 14 '18 at 13:18
  • Yes, it is possible. https://stackoverflow.com/questions/34107936/ef-update-multiple-rows-in-database-without-using-foreach-loop/34108011#34108011 – Steve Greene Feb 14 '18 at 14:06
  • Don't save in a loop. – johnny 5 Feb 14 '18 at 16:35
  • sorry for confusion, the save is my own method that does something quite complicated. Thanks @CamiloTerevinto thats what I was looking for, I cant upvote you because I have no points on this account – Josh Feb 14 '18 at 17:16
  • I think you can accept the answer, though. I will up vote for you. It is a good answer @CamiloTerevinto – DaniDev Feb 14 '18 at 23:33
  • BTW, does your Save method involve a TAP pattern ( System.Threading.Tasks.Task) ? If so, you may want to rethink using it in a loop. – DaniDev Feb 14 '18 at 23:37

1 Answers1

1

Depending on how you are using the elements (and how many there are), you may find it much better to load all entities at once:

// given List<int> idList
var tasks = _model.Tasks.Where(x => idList.Contains(x.id))

foreach (var task in tasks)
{
    Save(task, task.id);
}

Notice that Find performs a Where with the Primary Key, so you have to be careful if the entity does not have a Primary Key or if it has a composite one. You also don't get any compile-time safety of the type of the key (i.e you could pass a string to an entity with an int PK and find out at only run-time).
Of course, if the list is big enough, you may run into an OutOfMemoryException by bringing all data at once.

Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120