'Add' function adds two objects instead of one. Is this a bug?

rostamiani

Member
Joined
Oct 9, 2009
Messages
15
Programming Experience
10+
I'm using Entity Framework 6 with VB.NET.

The problem is that when I add a new 'user' object to the context, an additional user is added.

This is the code:

VB.NET:
Dim Db As New DbModel

' Create a new user
Dim NewUser = New User With {
    .UserName = txtUserName.Text.Trim,
    .Password = txtPassword.Text.Trim,
    .Department = cmbDepartment.SelectedValue,
    .UserGroup = CmbUserGroup.SelectedValue,
    .Owner = CurrentUser,
    .Enabled = True
}

' Add new user to the model
Db.Users.Add(NewUser)

See the count of users before and after adding

ftrMp.png

The first user that is added is NewUser object and the second one is CurrentUser!!!

Is this a bug?
 
I thought we already covered this on another site. If you add an entity to the context and that entity has other entities related to it that aren't already in the context then of course they get added too. How would it make sense not to? If it didn't happen that way and you saved NewUser back to the database then it would contain a foreign key for another record that didn't exist, which obviously wouldn't make sense. If you are saving an entity that is related to other entities then the assumption is that you want to save those entities too. If you don't want to save them, what are they doing there in the first place?

If your issue is that this other user already exists in the database then make sure that you get the entity via the context in first place, rather than creating a new object with the same data.
 
Thanks for your perfect explanation. Now I'm understanding the problem.

The CurrentUser already exists. Can I fix the problem by attaching current user to the context?
 
How are you getting/creating the CurrentUser? are you getting it from the context?

It's a little complicated...
I'm using a Login Form that saves current user in a public variable:

VB.NET:
        Dim UserQuery = From user In Db.Users
                        Where user.UserName = txtUserName.Text
                        Where user.Password = txtPassword.Text
                        Select user

        ' Add user info to the app
        CurrentUser = UserQuery.SingleOrDefault()

Then I'm getting this variable in the Main Form like this:

VB.NET:
        ' Show login form
        Dim LoginForm As New FrmLogin
        LoginForm.ShowDialog()

        ' If the user is not logged in, exit
        If LoginForm.CurrentUser Is Nothing Then
            Close()
            Return
        End If

        CurrentUser = LoginForm.CurrentUser

Then I'm sending this object to all forms like this:

VB.NET:
        ' Show user management form
        Dim MyForm As New FrmUsers(CurrentUser)
        MyForm.ShowDialog()

Finally, this variable is stored in a private variable in the destination form :

VB.NET:
    Private Db As New CodingDbModel

    Public Sub New(currentUser As User)
        InitializeComponent()
        Me.CurrentUser = currentUser
    End Sub

Then It's used in the new user:

VB.NET:
        ' Create a new user
        Dim NewUser = New User With {
            .UserName = txtUserName.Text.Trim,
            .Password = txtPassword.Text.Trim,
            .Department = cmbDepartment.SelectedValue,
            .UserGroup = CmbUserGroup.SelectedValue,
            .Owner = CurrentUser,
            .Enabled = True
        }

        Dim c = Db.Users.Local.Count
        ' Add new user to the model
        Db.Users.Add(NewUser)

How can I check if the user is validated in the context?
Thanks
 
I added the Attack method like this:

VB.NET:
Db.Users.Attach(CurrentUser)

And this error occurred:
System.InvalidOperationException: 'Attaching an entity of type 'Coding_Generator.User' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.'
 
Back
Top