brockallen / BrockAllen.MembershipReboot

MembershipReboot is a user identity management and authentication library.
Other
742 stars 238 forks source link

RemoveClaim causes validation exception. #621

Closed sheam closed 8 years ago

sheam commented 8 years ago

When I try to remove a claim from a custom user account I get this:

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

My user account does have a WarehouseId foreign key in it. Would this be the problem?

This is my c'tor:

        public MyContext(): base("ConStringName")
        {
            this.Configuration.LazyLoadingEnabled = true;
            this.RegisterUserAccountChildTablesForDelete<User>();
        }

I get the same error with or without those two lines of code in the c'tor.

My OnModelCreating looks like this:

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
            modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

            modelBuilder.Conventions.Add(new DecimalPrecisionAttributeConvention());

            //modelBuilder.ConfigureMembershipRebootUserAccounts<User>();
            base.OnModelCreating(modelBuilder);
        }

My User class looks like this:

    public class User : RelationalUserAccount
    {
        [MaxLength(50)]
        public virtual String FirstName { get; set; }

        [MaxLength(50)]
        public virtual String LastName { get; set; }

        [ForeignKey("WarehouseId")]
        public Warehouse DefaultWarehouse { get; set; }

        public Int32 WarehouseId { get; set; }
    }

I am on EF 6, .net 4.5.

Am I not allower to have Nav properties in my user account?

sheam commented 8 years ago

Ok, now I feel stupid... but hopefully this helps someone else. I forgot to make WarehouseId and DefaultWarehouse virtual property. Chaging to the following worked:

    public class User : RelationalUserAccount
    {
        [MaxLength(50)]
        public virtual String FirstName { get; set; }

        [MaxLength(50)]
        public virtual String LastName { get; set; }

        [ForeignKey("WarehouseId")]
        public virtual Warehouse DefaultWarehouse { get; set; }

        public virtual Int32 WarehouseId { get; set; }
    }
cbomkamp commented 8 years ago

Sorry for commenting on a closed issue, but I thought this might help someone else. I had the same problem so I made a unit test to ensure custom properties were virtual.

[Test]
public void AllCustomPropertiesMustBeVirtualToSupportDeletingOfChildCollectionItems()
{
    var properties = typeof(MyCustomUserClass).GetProperties(BindingFlags.DeclaredOnly | .BindingFlags.Public | BindingFlags.Instance);

    foreach (var accessor in properties.Select(property => property.GetAccessors().First()))
    {
        Assert.IsTrue(accessor.IsVirtual, string.Format("{0}.{1} was expected to be virtual but was not.", accessor.DeclaringType.Name, accessor.Name));
    }
}