我注意到其他人也遇到了同样的问题,例如无法将值 NULL 插入“UserId”列,但这应该是由不同的原因引起的。
问题可以这样简化:
UsersContext _usersContext = new UsersContext();
...
var usersInRole = new UsersInRole() { RoleId = 3, UserId = 1 };
_usersContext.UsersInRoles.Add(usersInRole);
_usersContext.SaveChanges();
最后一行代码抛出异常
“更新条目时发生错误。有关详细信息,请参阅内部异常。”
,并且 InnerException 说了同样的话
“更新条目时发生错误。有关详细信息,请参阅内部异常。”!
幸运的是,InnerException 的 InnerException 说
“无法将值 NULL 插入 'RoleId' 列,表 'MFC.dbo.webpages_UsersInRoles';列不允许空值。INSERT 失败。\r\n语句已终止。”
. 这意味着“RoleId = 3”已被修改或忽略,这怎么会发生?
下面列出了一些其他代码可能会有所帮助:
[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; }
}
和表创建脚本:
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])
);
另一件有趣的事是我可以从上下文中删除一个 usersInRole,即以下代码是可以的(如果我手动添加了记录):
UsersContext _usersContext = new UsersContext();
...
var usersInRole = _usersContext.UsersInRoles.SingleOrDefault(i => i.RoleId == 3 && UserId == 1);
_usersContext.UsersInRoles.Remove(usersInRole);
_usersContext.SaveChanges();
似乎很少有人使用和谈论简单的会员资格,因此我没有从 Google 找到很多有用的资源。因此,任何帮助将不胜感激。谢谢。
这是解决方案:
正如汤米所说,这个问题是由 [Key] 属性引起的。我没有删除 [Key](这将导致“实体类型未定义键”之类的错误),而是将代码更改为官方解决方案:
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!
}
}
}
似乎 Roles.AddUserToRole 和 Roles.RemoveUserFromRole 可以正确地做到这一点。但它还没有完成......奇怪的是,_userContext.UsersInRoles 无法返回正确的结果。例如,如果表中的数据是:
RoleId UserId
5 1
5 2
5 3
它返回 3 条记录 (5,1)(5,1)(5,1) 而不是 (5, 1)(5, 2)(5, 3)。这是汤米在他的回复中提到但被 Roles.Add/Remove() 绕过的事情。解决方法是: 1. 在表中添加一个 [ID] 列:
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. 将新列添加到 [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; }
}
现在我得到 (5, 1)(5, 2)(5, 3)!
我对数据库知之甚少,但正如 Tommy 所提到的,这应该是由于在脚本中将 [Key][Database....] 下的 RoleId 与 PRIMARY KEY CLUSTERED ([UserId] ASC, [RoleId] ASC) 一起声明造成的。