Der Wert NULL kann nicht in die Spalte 'RoleId' eingefügt werden (einfache Mitgliedschaft in MVC4)

Mir ist aufgefallen, dass jemand anderes das gleiche Problem hat wieDer Wert NULL kann nicht in die Spalte 'UserId' eingefügt werden aber es sollte aus verschiedenen Gründen verursacht werden.

Das Problem kann folgendermaßen vereinfacht werden:

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

Die letzte Codezeile hat eine Ausnahme ausgelöst

"Beim Aktualisieren der Einträge ist ein Fehler aufgetreten. Weitere Informationen finden Sie in der inneren Ausnahme."

, und die InnerException sagte dasselbe

"Beim Aktualisieren der Einträge ist ein Fehler aufgetreten. Einzelheiten finden Sie in der inneren Ausnahme."!

Zum Glück heißt es in der InnerException der InnerException

"Der Wert NULL kann nicht in die Spalte 'RoleId' in der Tabelle 'MFC.dbo.webpages_UsersInRoles' eingefügt werden. In der Spalte sind keine Nullen zulässig. INSERT schlägt fehl. \ R \ nDie Anweisung wurde abgebrochen."

. was bedeutet, dass "RoleId = 3" geändert oder ignoriert wurde, wie konnte das passieren?

Einige andere Codes könnten helfen, sind unten aufgeführt:

[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; }
}

und Tabellenerstellungsskripte:

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])
);

Interessant ist auch, dass ich eine usersInRole aus dem Kontext entfernen kann. Der folgende Code ist in Ordnung (wenn ich den Datensatz manuell hinzugefügt habe):

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

Es scheint, dass nur wenige Leute eine einfache Mitgliedschaft verwenden und darüber sprechen. Daher habe ich nicht viele hilfreiche Ressourcen von Google gefunden. So wird jede Hilfe geschätzt. Vielen Dank.

Hier ist die Lösung:

Wie Tommy sagte, wird dieses Problem durch die Attribute [Key] verursacht. Anstatt den [Schlüssel] zu löschen (was zu einem Fehler wie "Entitätstyp hat keinen Schlüssel definiert" führt), habe ich den Code in eine offizielle Lösung geändert:

            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!
                    }
                }
            }

Scheint, dass Roles.AddUserToRole und Roles.RemoveUserFromRole es richtig machen können. Aber es ist noch nicht fertig ... Seltsamerweise kann _userContext.UsersInRoles keine korrekten Ergebnisse zurückgeben. Zum Beispiel, wenn die Daten in der Tabelle sind:

RoleId UserId
5      1
5      2
5      3

Es werden 3 Datensätze (5,1) (5,1) (5,1) anstelle von (5, 1) (5, 2) (5, 3) zurückgegeben. Dies ist das, was Tommy in seiner Antwort erwähnte, aber von Roles.Add / Remove () umgangen wurde. Die Lösung lautet: 1. Fügen Sie der Tabelle eine [ID] -Spalte hinzu:

    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. Fügen Sie die neue Spalte der Entität RECHTS UNTER DEM [KEY] hinzu:

[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; }
}

Jetzt bekomme ich (5, 1) (5, 2) (5, 3)!

Ich weiß wenig über Datenbanken, aber wie Tommy erwähnt hat, sollte dies durch die Deklaration von RoleId unter [Key] [Database ....] mit PRIMARY KEY CLUSTERED ([UserId] ASC, [RoleId] ASC) in Skripten zusammen verursacht werden.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage