我使用ABP框架,我确实在更新问题上苦苦挣扎。我使用实体frmaework核心。
我将尽我所能去弄清楚。
我有一个类别表,其中包含类别名称和类别详细信息。
然后我要构建一个有角度的UI,该UI可以选择类别并将其存储在成就对象中。
那我的目标是存储成就和类别。
然后,我创建了一个表AccomplishementCategoryCustoms。
所以我的模型如下:
[Table("Accomplishments")]
public class Accomplishment : AuditedEntity
{
[Required]
public virtual string Name { get; set; }
public List<AccomplishementCategoryCustom> Categories { get; set; }
}
[Table("AccomplishementCategoryCustoms")]
public class AccomplishementCategoryCustom : CreationAuditedEntity
{
public virtual int? CategoryId { get; set; }
[ForeignKey("CategoryId")]
public Category CategoryFk { get; set; }
public virtual int? AccomplishmentId { get; set; }
[ForeignKey("AccomplishmentId")]
public Accomplishment AccomplishmentFk { get; set; }
}
我在类别和AccomplishementCategoryCustoms之间没有关系。
然后当我插入它时效果很好。
当我更新并添加包含时,出现以下错误:
当我更新时没有包含我会出现错误:
Microsoft.EntityFrameworkCore.DbUpdateException:更新条目时发生错误。有关详细信息,请参见内部异常。 ---> System.Data.SqlClient.SqlException:当IDENTITY_INSERT设置为OFF时,无法为表'AccomplishementCategoryCustoms'中的标识列插入显式值。
最后,模型构建器如下:
migrationBuilder.CreateTable(
name: "AccomplishementCategoryCustoms",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
CreationTime = table.Column<DateTime>(nullable: false),
CreatorUserId = table.Column<long>(nullable: true),
CategoryId = table.Column<int>(nullable: true),
AccomplishmentId = table.Column<int>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AccomplishementCategoryCustoms", x => x.Id);
table.ForeignKey(
name: "FK_AccomplishementCategoryCustoms_Accomplishments_AccomplishmentId",
column: x => x.AccomplishmentId,
principalTable: "Accomplishments",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_AccomplishementCategoryCustoms_Categories_CategoryId",
column: x => x.CategoryId,
principalTable: "Categories",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_AccomplishementCategoryCustoms_AccomplishmentId",
table: "AccomplishementCategoryCustoms",
column: "AccomplishmentId");
migrationBuilder.CreateIndex(
name: "IX_AccomplishementCategoryCustoms_CategoryId",
table: "AccomplishementCategoryCustoms",
column: "CategoryId");
}
我希望它将有足够详细的修复信息,因为很长一段时间以来我一直在苦苦挣扎,无法解决问题。
答案 0 :(得分:0)
好,所以我尝试了以下代码:
var accomplishment = _accomplishmentRepository.GetAll().AsNoTracking().Where(a =>
a.Id ==input.Id.Value)
.Include(a => a.Categories)
.FirstOrDefault();
var updatedEntity = ObjectMapper.Map(input, accomplishment);
await _accomplishmentRepository.UpdateAsync(updatedEntity);
我没有错误了 更新得很好。
但是,如果我在用户界面中取消选择一个自定义类别并进行更新,则应该删除数据库中的行。
很遗憾,更改未反映在数据库中。该行没有更改。
然后我尝试附加并设置修改后的内容,但出现以下错误:
如何解决此问题?
我真的不知道如何解决它。
答案 1 :(得分:0)
根据您的答案,假设_dbContextProvider.GetDbContext(Abp.MultiTenancy.MultiTenancySides.Host)
返回您要定位的数据库上下文(我从您的答案中得出),您可以使用以下代码来保持对成就的更改,包括添加或删除类别,假设以及ObjectMapper.Map(input, accomplishment)
是使用输入对从存储库接收的成就进行更改的原因,还假设ObjectMapper.Map(input, accomplishment)
返回的是实体类型。
async Task Update(CreateOrEditAccomplishmentsDto input)
{
var context = _dbContextProvider.GetDbContext(Abp.MultiTenancy.MultiTenancySides.Host);
context.Entry(ObjectMapper.Map(input, _accomplishmentRepository.GetAll().Where(a => a.Id == input.Id.Value).Include(a => a.Categories).FirstOrDefault())).State = EntityState.Modified;
await context.SaveChangesAsync();
}
从技术上讲,该行的context.Entry(...).State = EntityState.Modified
部分是多余的,但是我不确定您提供的任何内容的实现,因此我考虑了上下文实际上并没有从中跟踪返回的对象。致电Map
。
如果由于上下文已经跟踪id
具有相同值的实体而遇到异常,请删除以下行。
context.Entry(ObjectMapper.Map(input, _accomplishmentRepository.GetAll().Where(a => a.Id == input.Id.Value).Include(a => a.Categories).FirstOrDefault())).State = EntityState.Modified;
然后,在调用SaveChangesAsync
之前的位置添加以下行。
ObjectMapper.Map(input, _accomplishmentRepository.GetAll().Where(a => a.Id == input.Id.Value).Include(a => a.Categories).FirstOrDefault());