Victor
Victor

Reputation: 1108

How to get identity from multiple objects when adding those with Entity Framework?

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

Upvotes: 2

Views: 134

Answers (2)

Yacoub Massad
Yacoub Massad

Reputation: 27861

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).

Upvotes: 2

skalinkin
skalinkin

Reputation: 1064

Add this to your Task class

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TaskID { get; set; }

Upvotes: 0

Related Questions