我目前有2个相互映射的类。我收到以下错误:
MERGE语句与FOREIGN KEY约束冲突 " FK_Stories_Users_UserId&#34 ;.冲突发生在数据库中 " StoriesDb",table" dbo.Users",column' 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与数据库数据进行了比较,它们都是相同的值。
我在EF6中使用的只设置FK Id属性的技术可以按预期工作。
我是否在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);
});
答案 0 :(得分:0)
我使用相同的技术(设置UserId
值而不是完整的User
引用)并且它正常工作,只有一个添加 - 我在UserId
和{{1}之间使用显式FK绑定属性,像这样:
User
检查您的数据库(或迁移脚本) - 可能是EF在public Guid UserId { get; set; }
[ForeignKey(nameof(UserId))]
public virtual User User { get; set; }
中创建了两个不同的UserId
类似的属性而没有此属性?
当然,如果您愿意,可以使用流畅的API代替属性。