【发布时间】:2017-03-10 01:14:24
【问题描述】:
我目前有 2 个相互映射的类。我收到以下错误:
MERGE 语句与 FOREIGN KEY 约束冲突 “FK_Stories_Users_UserId”。数据库发生冲突 “StoriesDb”、表“dbo.Users”、“Id”列。
我正在尝试将 UserId FK 添加到我刚刚创建的新 Story 实体中。我的类看起来像这样(剪掉不相关的属性)
public class Story : ITimestamp
{
public Story() {}
public int Id { get; set; }
public string Description { get; set; }
public string DescriptionMarkdown { get; set; }
public string Title { get; set; }
public Guid UserId { get; set; }
public virtual User User { get; set; }
public virtual DateTime CreatedDate { get; set; }
public virtual DateTime ModifiedDate { get; set; }
}
public class User : ITimestamp
{
public Guid Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string PasswordHash { get; set; }
public string PasswordSalt { get; set; }
public virtual IList<Comment> Comments { get; set; } = new List<Comment>();
public virtual DateTime CreatedDate { get; set; }
public virtual DateTime ModifiedDate { get; set; }
}
我这样添加新故事:
public async Task<StorySummaryViewModel> Create(CreateViewModel model, string username, Guid userId)
{
var story = await StoriesDbContext.Stories.AddAsync(new Story() {
Title = model.Title,
DescriptionMarkdown = model.DescriptionMarkdown,
Description = CommonMarkConverter.Convert(model.DescriptionMarkdown),
UserId = userId
});
var rowCount = await StoriesDbContext.SaveChangesAsync();
[...]
}
通过其他一些 Create 方法,我知道将新实体对象添加到第二个新实体的导航属性将正确保存。但是,此时我不希望在保存 Story 实体时能够修改 User 实体,这就是我设置 UserId 属性(标记为 FK)的原因。但它似乎不起作用。
我还将传递给方法的 UserId 与数据库数据进行了比较,它们都是相同的值。
仅设置 FK Id 属性的技术是我在 EF6 中使用的,它按预期工作。
我是否在我的 DbContext 或我的映射中遗漏了一些允许我通过外键 ID 保存更改新实体的内容?
这个问题与this StackOverflow question 非常相似。但不幸的是,它只处理新创建的实体。
编辑 我包括我对故事和用户的映射。
public class StoryMap : IEntityTypeConfiguration<Story>
{
public void Map(EntityTypeBuilder<Story> builder)
{
builder.HasKey(e => e.Id);
builder.Property(s => s.Url).IsRequired();
builder.Property(s => s.Title).IsRequired();
builder.HasOne(e => e.User).WithMany().HasForeignKey(e => e.UserId);
builder.HasMany(e => e.Comments).WithOne(c => c.Story).HasForeignKey(c => c.StoryId);
builder.HasMany(e => e.Votes).WithOne(v => v.Story).HasForeignKey(v => v.StoryId);
}
}
public class UserMap : IEntityTypeConfiguration<User>
{
public void Map(EntityTypeBuilder<User> builder)
{
builder.HasKey(u => u.Id);
builder.HasIndex(u => u.Email);
builder.Property(u => u.PasswordHash).IsRequired();
builder.Property(u => u.PasswordSalt).IsRequired();
builder.Property(u => u.Username).IsRequired();
builder.Property(u => u.Email).IsRequired();
// Navigation
[..snip..]
builder.HasMany(u => u.Stories).WithOne(c => c.User).HasForeignKey(s => s.UserId);
}
}
为迁移编辑
migrationBuilder.CreateTable(
name: "Stories",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
CreatedDate = table.Column<DateTime>(nullable: false),
Description = table.Column<string>(nullable: true),
DescriptionMarkdown = table.Column<string>(nullable: true),
ModifiedDate = table.Column<DateTime>(nullable: false),
Title = table.Column<string>(nullable: false),
Url = table.Column<string>(nullable: false),
UserId = table.Column<Guid>(nullable: false),
UserIsAuthor = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Stories", x => x.Id);
table.ForeignKey(
name: "FK_Stories_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
【问题讨论】:
标签: asp.net-core-mvc entity-framework-core