“更新条目时发生错误”。在EF中,当我尝试将SaveChanges()传递到上下文时 [英] "An error occurred while updating the entries" in EF when I try to SaveChanges() to context

查看:263
本文介绍了“更新条目时发生错误”。在EF中,当我尝试将SaveChanges()传递到上下文时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了两个与我的两个班级相对应的列表:

I've created two lists that corresponds to two of my classes:

//Photo
        var photos = new List<Photo>{
            new Photo {
                Title = "Title1",
                Description = "Description1",
                CreatedDate = DateTime.Today
            }
        };

        //Comment
        var comments = new List<Comment>
        {
            new Comment{
                PhotoId = 1,
                UserName = "User1",
                Subject = "Comment1",
            }
        };

当我尝试将这两个列表添加到上下文对象然后保存到SaveChanges时,出现了错误提到:

When I tried to add these two lists to my context object and then SaveChanges, I got the error I mentioned:

photos.ForEach(s => context.Photos.Add(s));
comments.ForEach(s => context.Comments.Add(s));

context.SaveChanges();

但是当我单独保存更改时,没有得到例外。

But when I saved the changes individually, I didn't get the exception.

        photos.ForEach(s => context.Photos.Add(s));
        context.SaveChanges();

        comments.ForEach(s => context.Comments.Add(s));
        context.SaveChanges();

为什么?每次修改数据库后,我都应该保存更改吗?

Why is this? Should I save changes after each modification of my DB?

推荐答案

为避免此类问题,请设置实体与使用这些关系,而不是尝试手动设置FK ID。

To avoid issues like this, set up the relationships between your entities and use those relationships rather than trying to set FK IDs manually. ORMs like EF are designed to work this detail out for you, so leverage that ability.

如果照片有评论,评论中带有PhotoID列,则可以设置EF。实体是这样的:

If a photo has comments, where a comment has a PhotoID column then set up the entities something like this:

public class Photo
{
   public int PhotoID {get; set;}
   public string Title {get; set;}
   public string Description {get; set;}

   private List<Comment> _comments = new List<Comment>();
   public virtual List<Comment> Comments 
   {
      get {return _comments;}
      set {_comments = value;}
   }
}

public class Comment
{
   public string UserName {get; set;}
   public string Subject {get; set;}
}

请注意,我没有添加PhotoID来发表评论。例如,如果您要搜索评论并导航回照片,则可以选择添加:

Note that I haven't added PhotoID to comment. If you want to search for comments for instance and navigate back to a Photo then you can optionally add:

public virtual Photo Photo {get; set;}

但是,如果您不需要该导航,那么我会避免将其添加到保持简单。

However if you don't need that navigation, then I'd avoid adding it to keep things simple.

要设置这些导航属性,以便EF可以管理它们,我使用EntityTypeConfiguration映射。还有一些使用数据批注的方法,但是我发现ETConfig更可靠。

To set up these navigation properties so EF can manage them, I use EntityTypeConfiguration mappings. There are also methods using data annotations, but I find ETConfigs more reliable.

public class PhotoConfiguration : EntityTypeConfiguration<Photo>
{
   public PhotoConfiguration()
   {
      ToTable("Photos");
      HasKey(x => x.PhotoID)
         .Property(x => x.PhotoID)
         .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); // This informs EF that the database will be assigning the PK.

      HasMany(x => x.Comments)
         .WithRequired()
         .Map(x => x.MapKey("PhotoID")); // This tells EF to join comments to a Photo /w the PhotoID on the Comment table. HasMany says a Photo has many comments, and WithRequired() points to a non-nullable FK on Comment, but no navigation property coming back to Photo.
   }
}

此示例适用于EF6,对于EFCore,您可以替换.map()调用/ w

This example is for EF6, for EFCore you can replace the .Map() call /w

.HasForeignKey("PhotoID");

这将通过shadow属性完成相同的操作。如果确实要在每个注释上引用照片,则可以在注释中添加虚拟属性,然后将 .WithRequired()替换为。 WithRequired(x => x.Photo),这将建立关系。

which will accomplish the same thing with a shadow property. If you do want a reference to Photo on each Comment, then you can add the virtual property in Comment, then replace the .WithRequired() with .WithRequired(x => x.Photo) and this will set up the relationship.

public class CommentConfiguration : EntityTypeConfiguration<Comment>
{
   public CommentConfiguration()
   {
      ToTable("Comments");
      HasKey(x => x.CommentID)
         .Property(x => x.CommentD)
         .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
   }
}

现在,当您要保存照片和评论时:

Now when you want to save a photo and a comment:

   var photo = new Photo 
   {
      Title = "Title1",
      Description = "Description1",
      CreatedDate = DateTime.Today,
      Comments = new[] 
      {
         New Comment { UserName = "User1", Subject = "Comment1" }
      }.ToList()
   };
   context.Photos.Add(photo);
   context.SaveChanges();

请注意,我们不会单独保存评论。 EF在后台管理所有PK / FK。保存更改后,我们可以从实体属性中检索实体的PK。

Note that we don't save Comments separately. EF manages all of the PK/FK behind the scenes. After the SaveChanges we can retrieve the PKs of our entities from the entity properties.

这篇关于“更新条目时发生错误”。在EF中,当我尝试将SaveChanges()传递到上下文时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆