1

I'm trying to add an object to a navigation property of an entity but I keep getting this exception.

System.InvalidOperationException
An object of type 'System.Collections.ObjectModel.Collection`1[[WakeSocial.BusinessProcess.Core.Domain.UserDevice, WakeSocial.BusinessProcess.Core.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' cannot be set or removed from the Value property of an EntityReference of type 'WakeSocial.BusinessProcess.Core.Domain.UserDevice'.

Adding entity

    UserDevice device = new UserDevice();
    device.DeviceType = type;
    device.DeviceId = deviceId;
    device.PushId = pushId;
    device.HasFrontFacingCamera = hasFrontCamera;

    user.Devices.Add(device);
    await UpdateUser(user);


  public async Task<User> UpdateUser(User user)
  {
      Context.Entry(user).State = EntityState.Modified;
      await uow.SaveChangesAsync();
      return user;
  }

My domain model

public enum Gender
{
    Male = 0,
    Female = 1
}
public class User
{
    public Guid UserId { get; private set; }

    public string FacebookUserId { get; set; }
    public string FacebookAccessToken { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public Gender Gender { get; set; }
    public int TokenCount { get; set; }


    public virtual ICollection<UserDevice> Devices { get; set; }
    public virtual ICollection<Beat> OwnedBeats { get; set; }

    public User()
    {
        UserId = GuidComb.Generate();
        Devices = new Collection<UserDevice>();
    }
}

If I should remove the collection initialization and just try to add the object I will get a null reference exception.

System.NullReferenceException
Object reference not set to an instance of an object.

So my question is how are navigation properties initialized? I thought just having the virtual keyword did all of this. \

UPDATE

This is present in the DbContext

      //User
      modelBuilder.Entity<User>()
          .HasOptional(u => u.Devices)
          .WithMany()
          .WillCascadeOnDelete();

UserDevice

 public class UserDevice
{
    public Guid UserDeviceId {get;private set;}
    public DeviceType DeviceType { get; set; }
    public string DeviceId { get; set; }
    //local GSM/Apple Push Id
    public string PushId { get; set; }
    //RegistrationId from Azure Hubs
    public string HubId { get; set; }

    public bool HasFrontFacingCamera { get; set; }

    public UserDevice()
    {
        UserDeviceId = GuidComb.Generate();
    }
}
Joel Dean
  • 2,444
  • 5
  • 32
  • 50
  • What does your UpdateUser code look like? Also, are the PKs getting generated in your DB for your User and UserDevice tables? Are you manually setting the UserId and keeping track of the identities yourself? My gut tells me there may be an issue with your mappings and PKs. – DDiVita Aug 24 '15 at 15:17
  • @DDiVita I just added the updateUser code... I am generating the primary key myself using GuidComb.Generator similar to this http://stackoverflow.com/questions/1752004/sequential-guid-generator so yes I set the user id myself.. What do you mean interms of tracking identities myself? – Joel Dean Aug 24 '15 at 15:38
  • @DDiVita I added a cascade and delete config from my context. It might be where the error is taking place because it started occurring after it was added. – Joel Dean Aug 24 '15 at 15:46

1 Answers1

0

Try this:

modelBuilder.Entity<User>()
          .HasMany(u => u.Devices)
          .WithOptional(d => d.User) 
          .Map(c => c.MapKey("UserId"));
DDiVita
  • 4,225
  • 5
  • 63
  • 117