• Hello and welcome to our new forums. We upgraded our forum sites to a more robust and modern system which we hope you will enjoy. Be sure to check out your profile by clicking the button on the top right and configure your preferences, signature, time zone, avatar, etc. as you wish. If you need help with using this new forum'ware try the help link on the bottom right.

    Click here to review your account now.

'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:

Code:
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?
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,031
Location
Sydney, Australia
Programming Experience
10+
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.
 

rostamiani

Member
Joined
Oct 9, 2009
Messages
15
Programming Experience
10+
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?
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,031
Location
Sydney, Australia
Programming Experience
10+
How are you getting/creating the CurrentUser? are you getting it from the context?
 

rostamiani

Member
Joined
Oct 9, 2009
Messages
15
Programming Experience
10+
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:

Code:
        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:

Code:
        ' 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:

Code:
        ' 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 :

Code:
    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:

Code:
        ' 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
 

rostamiani

Member
Joined
Oct 9, 2009
Messages
15
Programming Experience
10+
I added the Attack method like this:

Code:
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.'
 
Top Bottom