Nie można wstawić wartości NULL do kolumny „RoleId” (proste członkostwo mvc4)

Zauważyłem, że ktoś inny miał taki sam problem jakNie można wstawić wartości NULL do kolumny „UserId” ale powinno to być spowodowane różnymi przyczynami.

Problem można uprościć w ten sposób:

            UsersContext _usersContext = new UsersContext();
            ...
            var usersInRole = new UsersInRole() { RoleId = 3, UserId = 1 };
            _usersContext.UsersInRoles.Add(usersInRole);
            _usersContext.SaveChanges();

Ostatnia linia kodu rzuciła wyjątek

„Wystąpił błąd podczas aktualizowania wpisów. Szczegółowe informacje zawiera wyjątek wewnętrzny.”

, a InnerException mówił to samo

„Wystąpił błąd podczas aktualizacji wpisów. Szczegółowe informacje zawiera wyjątek wewnętrzny.”!

Na szczęście mówi InnerException z InnerException

„Nie można wstawić wartości NULL do kolumny„ RoleId ”, tabela„ MFC.dbo.webpages_UsersInRoles ”; kolumna nie zezwala na wartości null. INSERT nie powiedzie się.

. co oznacza, że ​​„RoleId = 3” zostało zmodyfikowane lub zignorowane, jak mogło do tego dojść?

Pomocny może być inny kod wymieniony poniżej:

[Table("webpages_UsersInRoles")]
public partial class UsersInRole
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int RoleId { get; set; }
    public int UserId { get; set; }
}

public class UsersContext : DbContext
{
    public UsersContext()
        : base("MFCConnectionString")
    {
    }

    public DbSet<UsersInRole> UsersInRoles { get; set; }
}

i skrypty do tworzenia tabel:

CREATE TABLE [dbo].[webpages_UsersInRoles] (
    [UserId] INT NOT NULL,
    [RoleId] INT NOT NULL,
    PRIMARY KEY CLUSTERED ([UserId] ASC, [RoleId] ASC),
    CONSTRAINT [fk_UsersInRoels_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [dbo].[webpages_Roles] ([RoleId]),
    CONSTRAINT [fk_UsersInRoles_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[UserProfile] ([UserId])
);

Inną przeszkodą jest to, że mogę usunąć userInRole z kontekstu, a mianowicie następujący kod jest w porządku (jeśli dodałem go ręcznie):

            UsersContext _usersContext = new UsersContext();
            ...
            var usersInRole = _usersContext.UsersInRoles.SingleOrDefault(i => i.RoleId == 3 && UserId == 1);
            _usersContext.UsersInRoles.Remove(usersInRole);
            _usersContext.SaveChanges();

Wydaje się, że niewiele osób korzysta z prostego członkostwa i mówi, że nie znalazłem wielu przydatnych zasobów od Google. Więc każda pomoc zostanie doceniona. Dzięki.

Oto rozwiązanie:

Jak powiedział Tommy, ten problem jest spowodowany atrybutami [Klucz]. Zamiast usuwać [Klucz] (co spowoduje błąd taki jak „typ jednostki nie ma zdefiniowanego klucza”), zmieniłem kod na rozwiązanie oficjalne:

            foreach (var role in roles)
            {
                foreach (var user in UserProfile.GetAllUserProfiles(_usersContext))
                {
                    var usersInRole = _usersContext.UsersInRoles.SingleOrDefault(uio => uio.RoleId == role.RoleId && uio.UserId == user.UserId);
                    var key = user.UserId + "_" + role.RoleId;
                    if (collection.AllKeys.Any(i => i == key) && collection[key].Contains("true") && usersInRole == null)
                    {
                        Roles.AddUserToRole(user.UserName, role.RoleName); //Key codes!
                    }
                    if (collection.AllKeys.Any(i => i == key) && !collection[key].Contains("true") && usersInRole != null)
                    {
                        Roles.RemoveUserFromRole(user.UserName, role.RoleName); //Key codes!
                    }
                }
            }

Wydaje się, że Roles.AddUserToRole i Roles.RemoveUserFromRole mogą to zrobić poprawnie. Ale to jeszcze nie koniec ... Dziwne, _userContext.UsersInRoles nie może zwrócić poprawnych wyników. Na przykład, jeśli dane w tabeli to:

RoleId UserId
5      1
5      2
5      3

zwraca 3 rekordy (5,1) (5,1) (5,1) zamiast (5, 1) (5, 2) (5, 3). To jest rzecz, o której wspomniał Tommy w swojej odpowiedzi, ale pominięta przez Role.Add / Remove (). Rozwiązaniem jest: 1. Dodaj kolumnę [ID] do tabeli:

    CREATE TABLE [dbo].[webpages_UsersInRoles] (
        [ID] INT NOT NULL IDENTITY, --Key codes!
        [UserId] INT NOT NULL,
        [RoleId] INT NOT NULL,
        PRIMARY KEY CLUSTERED ([UserId] ASC, [RoleId] ASC),
        CONSTRAINT [fk_UsersInRoels_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [dbo].[webpages_Roles] ([RoleId]),
        CONSTRAINT [fk_UsersInRoles_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[UserProfile] ([UserId])
    );

2. Dodaj nową kolumnę do encji RIGHT UNDER THE [KEY]:

[Table("webpages_UsersInRoles")]
public partial class UsersInRole
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; } //Key codes!
    public int RoleId { get; set; }
    public int UserId { get; set; }
}

Teraz dostaję (5, 1) (5, 2) (5, 3)!

Niewiele wiem o bazie danych, ale jak wspomniał Tommy, powinno to być spowodowane zadeklarowaniem RoleId w [Key] [Database ....] z PRIMARY KEY CLUSTERED ([UserId] ASC, [RoleId] ASC) w skryptach razem.

questionAnswers(2)

yourAnswerToTheQuestion