c# - Entity Framework Code First 现有数据库集 EntityState.Unchanged on Many-to-Many

标签 c# entity-framework entity-framework-6

我有一个现有的数据库,我正在使用 Entity Framework 6 Code First 进行编码。我有一个适用于选择、插入和删除的多对多关系。我在 EF 为现有关系的多对多表添加额外插入时遇到问题。

架构: enter image description here

数据库上下文:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
       Database.SetInitializer<MainContext>(null);

       modelBuilder.Entity<DocumentType>()
                .HasMany(u => u.DocumentStatuses)
                .WithMany()
                .Map(m =>
                {
                    m.MapLeftKey("DOCUMENT_TYPE_ID");
                    m.MapRightKey("DOCUMENT_STATUS_ID");
                    m.ToTable("DOCUMENT_TYPES_DOCUMENT_STATUSES");
                });

       base.OnModelCreating(modelBuilder);
    } 

DTO:

    [Table("DOCUMENT_TYPES")]
    public class DocumentType
    {
        [Key]
        [Column("DOCUMENT_TYPE_ID")]
        public int? Id { get; set; }

        [Required]
        [Column("TYPE_NAME")]
        public string TypeName { get; set; }

        [Required]
        [Column("IS_ACTIVE")]
        public bool IsActive { get; set; }

        [Display(Name = "Updated By")]
        [Column("LAST_UPDATED_BY")]
        public string LastUpdatedBy { get; set; }

        [Display(Name = "Updated Date")]
        [Column("LAST_UPDATED_DATE")]
        public DateTimeOffset? LastUpdatedDate { get; set; }

        public virtual List<DocumentStatus> DocumentStatuses { get; set; } 

        public DocumentType()
        {
            DocumentStatuses = new List<DocumentStatus>();
        }
    }

[Table("DOCUMENT_STATUSES")]
public class DocumentStatus
{
    [Key]
    [Column("DOCUMENT_STATUS_ID")]
    public int? Id { get; set; }

    [Required]
    [Column("STATUS_NAME")]
    public string StatusName { get; set; }

    [Required]
    [Column("IS_COMPLETE")]
    public bool IsComplete { get; set; }

    [Required]
    [Column("IS_ACTIVE")]
    public bool IsActive { get; set; }

    [Display(Name = "Updated By")]
    [Column("LAST_UPDATED_BY")]
    public string LastUpdatedBy { get; set; }

    [Display(Name = "Updated Date")]
    [Column("LAST_UPDATED_DATE")]
    public DateTimeOffset? LastUpdatedDate { get; set; }
}

存储库更新:

    public bool Update(DocumentType entity, string updatedBy)
            {
                DateTimeOffset updatedDateTime = DateTimeOffset.Now;

                entity.LastUpdatedBy = updatedBy;
                entity.LastUpdatedDate = updatedDateTime;

                using (var db = new MainContext())
                {
                    db.DocumentTypes.Add((DocumentType)entity);
                    db.Entry(entity).State = EntityState.Modified;

                    foreach (var item in entity.DocumentStatuses)
                    {
                        if (item.Id != null)
                            db.Entry(item).State = EntityState.Unchanged;
                    }

                    db.SaveChanges();
                }

                return true;
            }

循环包含:

    if (item.Id != null)
     db.Entry(item).State = EntityState.Unchanged;

防止添加新记录,但 EF 仍尝试将现有多对多记录的副本插入到 DOCUMENT_TYPES_DOCUMENT_STATUSES 中。

单元测试:

        [TestMethod()]
        public void UpdateTest()
        {
            DocumentTypeRepository documentTypeRepository = new DocumentTypeRepository();
            DocumentType type = NewDocumentType(true);
            DocumentType typefromDb;
            string updatedBy = "DocumentTypeRepositoryTests.UpdateTest";
            bool actual;

            type.IsActive = true;
            type.TypeName = RandomValues.RandomString(18);
            type.DocumentStatuses.Add(DocumentStatusRepositoryTests.NewDocumentStatus(true));

            actual = documentTypeRepository.Update(type, updatedBy);
            Assert.AreEqual(true, actual);

            typefromDb = documentTypeRepository.GetById((int)type.Id);
            Assert.AreEqual(type.DocumentStatuses.Count, typefromDb.DocumentStatuses.Count);
        }

当多对多表已经存在时,如何将其设置为 EntityState.Unchanged?

最佳答案

尝试替换

db.DocumentTypes.Add((DocumentType)entity);
db.Entry(entity).State = EntityState.Modified;

db.Entry(entity).State = entity.Id == null 
    ? EntityState.Added
    : EntityState.Modified;

当对分离的实体进行 CRUD 操作时,不使用 DbSet 操作而只操作实体状态条目会更容易。至少,它会导致更少的错误。

关于c# - Entity Framework Code First 现有数据库集 EntityState.Unchanged on Many-to-Many,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27694854/

相关文章:

c# - 机会实体的 crm2011 插件问题

c# - 类似于 Extension Methods Functionality - 我们可以扩展属性吗

c# - 局部变量清理的异步等待问题

c# - 使用字符串操作和正则表达式的 LINQ 查询结果

javascript - 如何使用页面方法将控件绑定(bind)到不同的数据源?

c# - 在发送到数据库之前,使 EF 将可转换为字符串类型的属性转换为字符串

linq - 获取组中存在的第一项和最后一项

entity-framework - EF 6数据库第一个: How to update stored procedures?

c# - 即使定义了其他主键, Entity Framework 6 也会创建 Id 列

c# - Entity Framework 6 : related entities auto added to parent entity despite lazy loading being turned off