尝试在“引用”表中插入多行,但出现错误IDENTITY_INSERT

时间:2020-09-15 22:06:07

标签: c# asp.net-core entity-framework-core

所以我想做的是获取带有ID的帖子列表,然后使用Linq EFcore将其循环并添加到数据库中,但是如果帖子中只有多个ID,则当我有多个ID时出现错误效果很好。

public async Task<IActionResult> Create([Bind("Name,IsPublished,CretedDate,ModifiyDate,posts")] Tag tag,List<int> posts)
{
    if (ModelState.IsValid)
    {
        foreach (var item in posts)
        {
            var _post = _contextPosts.dbcontext.Post.Find(item); // fetch one record from posts 
            tag.PostTag = new List<PostTag> //Tag
            {
                 new PostTag 
                 {
                      Post = _post,
                      Tag = tag
                      }
            };
            
            _contextTags.dbcontext.Add(tag);

            await _contextTags.dbcontext.SaveChangesAsync();
        }
    }
}

ni

表格

public class Post
{
    [Key]
    public int Id { get; set; }
    [Display(Name = "Created By:")]
    public AppUser AuthorId { get; set; }
    [Required]
    public string Title { get; set; }
    public string metaTitle { get; set; }
    [Required]
    public string Body { get; set; }
    public bool IsPublished { get; set; } = true;
    public bool IsFeatured { get; set; } = false;
    public DateTime CretedDate { get; set; } = DateTime.Now;
    public DateTime ModifiyDate { get; set; } = DateTime.Now;
    public ICollection<Comment> Comments { get; set; }
    public ICollection<PostTag> Tags { get; set; }
}

public class Tag
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    public bool IsPublished { get; set; } = true;
    public DateTime CretedDate { get; set; } = DateTime.Now;
    public DateTime ModifiyDate { get; set; } = DateTime.Now;
    public ICollection<PostTag> PostTag { get; set; }
    public ICollection<Images> Images { get; set; }
}

public class PostTag
{
    public int TagId { get; set; }
    public int PostId { get; set; }
    public Post Post { get; set; }
    public Tag Tag { get; set; }
    public AppUser AppUser { get; set; }
}       

3 个答案:

答案 0 :(得分:1)

似乎您的数据库中已经有一些帖子记录,并且您希望将这些帖子附加到标签上。

在这种情况下,您可以先将标签添加到Tag表中,然后检索最新插入的Tag实体的ID。然后将TagId和PostId插入PostTag表。

请参阅以下代码:

public async Task<IActionResult> IndexAsync()
{
    List<int> posts = new List<int> { 1, 2, 3 };
    Tag tag = new Tag
    {
        Name = "T1",
        IsPublished = true,
        CretedDate = DateTime.Now,
        ModifiyDate = DateTime.Now
    };

    _context.Tag.Add(tag);
    await _context.SaveChangesAsync();
    int tagId = tag.Id;

    foreach (var item in posts)
    {
        _context.PostTag.Add(new PostTag { TagId = tagId, PostId = item });
        await _context.SaveChangesAsync();
    }

    return View();
}

dbo.Post:

enter image description here

结果:

enter image description here

答案 1 :(得分:0)

我猜想PostTagsPostTags的多对多中间表。我认为您不应该手动进行更新;这样可以更轻松地构建对象结构,并让Entity Framework添加中间记录。所以更像是:

 public async Task<IActionResult> Create([Bind("Name,IsPublished,CretedDate,ModifiyDate,posts")] Tag tag, List<int> posts)
    {
    
        if (ModelState.IsValid)
        {
            foreach (var item in posts)
            {
                var post = _dbcontext.Post.Find(item);
                post.Tags.Add(tag);

                await _dbcontext.SaveChangesAsync();
            }
        }

答案 2 :(得分:0)

该错误表明您正在尝试保存已经设置了主键的Tag实体。这意味着您不会尝试创建新的Tag-该标记已存在于数据库中,只是将其链接到帖子。

如果是这种情况,那么-

  1. 首先获取现有的Tag及其PostTag集合
  2. 将每个新创建的PostTag添加到现有PostTag集合中
  3. 保存现有的Tag
// Fetch existing Tag including its PostTag collection
var existingTag = await context.Tags.Include(p => p.PostTags).FirstOrDefaultAsync(p => p.Id == tag.Id);

foreach (var item in posts)
{
    var existingPost = await context.Posts.FindAsync(item.Id);
    
    // Add to the existing PostTag collection
    existingTag.PostTags.Add(new PostTag { Post = existingPost });
}

// Save existing Tag
await context.SaveChangesAsync();