列 'UserId' に値 NULL を挿入できないなど、他の誰かが同じ問題に直面していることに気付きましたが、別の理由で発生するはずです。
問題は次のように単純化できます。
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' に挿入できません。列は NULL を許可しません。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])
);
もう 1 つの興味深い点は、usersInRole をコンテキストから削除できることです。つまり、次のコードは問題ありません (手動でレコードを追加した場合)。
UsersContext _usersContext = new UsersContext();
...
var usersInRole = _usersContext.UsersInRoles.SingleOrDefault(i => i.RoleId == 3 && UserId == 1);
_usersContext.UsersInRoles.Remove(usersInRole);
_usersContext.SaveChanges();
単純なメンバーシップを使用して話している人はほとんどいないようです. そのため、どんな助けでも大歓迎です。ありがとう。
解決策は次のとおりです。
Tommy が言ったように、この問題は [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
(5, 1)(5, 2)(5, 3) ではなく、3 つのレコード (5,1)(5,1)(5,1) を返します。これは、Tommy が返信で言及したことですが、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. [キー] の下のエンティティに新しい列を追加します。
[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) で宣言することによって引き起こされるはずです。