2

I have the following function:

public IEnumerable<Task> AddTasks(IEnumerable<Task> tasks)
{
   foreach (Task task in tasks)
   {
      Db.Tasks.Add(task);
   }

   Db.SaveChanges();
   return tasks;
}

I need to insert multiple objects within this function. However when returning tasks, the objects are the same as when i sent those, TaskID (identity) still has a value of 0.

I tried this one after savechanges but it crashed:

//Revive object
foreach (Task task in tasks)
{
   Db.Entry(task).GetDatabaseValues();
}

How can I obtain the identity of those items?

Edit:

public partial class Task
    {
        public int TaskID { get; set; }
        public int ProjectID { get; set; }
        public bool IsActive { get; set; }
        public System.DateTime CreatedDate { get; set; }
    }

public void AddTasksUsingViewModels(IEnumerable<TaskVM> taskVms)
{
    IEnumerable<Task> tasksToAdd = taskVms.Select
    (
        t => 
        new Task
        {
            ProjectID = taskVm.ProjectID,
            IsActive = true,
            CreatedDate = DateTime.Now
        }
    );

    IEnumerable<Task> entityList = AddTasks(tasksToAdd);
}
Victor
  • 1,108
  • 9
  • 29
  • 53
  • what type of your TaskID? int, GUID? – skalinkin Dec 10 '15 at 15:46
  • http://stackoverflow.com/questions/16079217/how-to-generate-and-auto-increment-id-with-entity-framework – skalinkin Dec 10 '15 at 15:47
  • please show your Task class declaration. – skalinkin Dec 10 '15 at 15:51
  • Try to call the Refresh method with the StoreWins value for refreshMode after you call SaveChanges – vitalygolub Dec 10 '15 at 15:59
  • what is your mapping logic of Task, if it's an identity field, I am assuming it's auto-incremented. not sure which version of EF you are using, but based on my previous experience, don't you need to have somewhere to set EntityState to Add? otherwise, they will be seen as the same. There are different framework that can do it automatically, but maybe the new EF doesn't have to do it anymore... – sowen Dec 10 '15 at 16:02

2 Answers2

2

You are returning the same IEnumerable<Task> tasks that you got as an input to your AddTasks.

When you iterate over the same IEnumerable<Task> object more than one time, you are not guaranteed to get the same set of objects. This is specially true in your case because the tasksToAdd object that you pass to the AddTasks method is one that is created using the Select LINQ method (taskVms.Select ...). The Select method returns an IEnuemrable that will generate the items every time you iterate over it.

You might want to read about deferred execution with IEnumerable<T> and LINQ.

To verify this and fix it, simply convert the enumerable to a list before invoking the AddTasks method like this:

IEnumerable<Task> entityList = AddTasks(tasksToAdd.ToList());

List<T> implements IEnumerable<T>. However, it is guaranteed that List<T> will return the same set of objects when you enumerate it multiple times (Assuming of course that no one added or removed items from the list).

Yacoub Massad
  • 27,509
  • 2
  • 36
  • 62
0

Add this to your Task class

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TaskID { get; set; }
skalinkin
  • 1,024
  • 9
  • 19