[英]InsertAndGetIdAsync - Cannot insert explicit value for identity column
使用ASPNET Boilerplate(.NET Framework)3.6.1
我已经成功地在许多实体上使用了AsyncCrudAppService,没有出现问题,但是我遇到了一个我无法插入的特定实体类型的问题,因为Entity Framework似乎认为它已被提供了显式ID。
我的实体:
public class Attendance : FullAuditedEntity<int>
{
[Required]
public Guid Guid { get; set; }
public long? UserId { get; set; }
[Required]
public int EventId { get; set; }
public int StatusId { get; set; }
[Required]
[MaxLength(100)]
public string InviteEmail { get; set; }
[Required]
[MaxLength(20)]
public string InviteCode { get; set; }
public bool InviteAccepted { get; set; }
public DateTime? InviteAcceptedDate { get; set; }
public string InviteSource { get; set; }
public long? InvitedByUserId { get; set; }
[ForeignKey("UserId")]
public User User { get; set; }
[ForeignKey("InvitedByUserId")]
public User InvitedByUser { get; set; }
[ForeignKey("EventId")]
public Event Event { get; set; }
[ForeignKey("StatusId")]
public AttendanceStatus Status { get; set; }
}
我的CreateDto
[AutoMapTo(typeof(Attendance))]
public class CreateAttendanceDto
{
public long? UserId { get; set; }
[Required]
public int EventId { get; set; }
public int StatusId { get; set; }
[Required]
[MaxLength(100)]
public string InviteEmail { get; set; }
public bool InviteAccepted { get; set; }
public DateTime? InviteAcceptedDate { get; set; }
public string InviteSource { get; set; }
public long? InvitedByUserId { get; set; }
}
我的AppService的Create方法:
public override async Task<AttendanceDto> Create(CreateAttendanceDto input)
{
var attendance = ObjectMapper.Map<Attendance>(input);
attendance.InviteCode = "TEST";
// Create GUID
attendance.Guid = Guid.NewGuid();
await _attRepository.InsertAndGetIdAsync(attendance);
return MapToEntityDto(attendance);
}
调试实体表明正在将id:0发送到insert方法。 这与可以正常工作的另一个实体插入完全相同。
在SQL事件探查器中跟踪两个不同的实体插入查询,我可以看到工作的对象已从插入查询中删除了ID,其中上面一个不起作用的对象正在尝试将id = 0插入数据库中,这显然是问题。
InsertAndGetIdAsync调用返回的错误如下:
错误2018-07-10 17:29:06,249 [108] nHandling.AbpApiExceptionFilterAttribute-更新条目时发生错误。 有关详细信息,请参见内部异常。 System.Data.Entity.Infrastructure.DbUpdateException:更新条目时发生错误。 有关详细信息,请参见内部异常。 ---> System.Data.Entity.Core.UpdateException:更新条目时发生错误。 有关详细信息,请参见内部异常。 ---> System.Data.SqlClient.SqlException:当IDENTITY_INSERT设置为OFF时,无法为表'Attendance'中的Identity列插入显式值。
我已经检查并仔细检查了这两个appservice Creates及其相关实体和dto之间的差异,但找不到任何差异。 甚至有一个同事来验证。
知道这里可能会发生什么吗?
您需要为实体Attendance
指定一个映射,以便它不会尝试在ID列中插入值。 简而言之,您需要让EF知道ID列已配置为IDENTITY。 异常消息非常清楚地说明了这一点。
System.Data.SqlClient.SqlException:当IDENTITY_INSERT设置为OFF时,无法为表'Attendance'中的Identity列插入显式值。
使用属性:
public class Attendance {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long AttendanceId { get; set; }
}
或在DbContext
类型的流利映射中
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<Attendance>().Property(t => t.AttendanceId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
我发现了这个隐患。
在我的DbContext中,我以前曾尝试为Guid字段提供一个默认值(我现在意识到,这也使它成为EF的标识列)。 最后这没有用,但我忽略了整理它:
modelBuilder.Entity<Attendance>()
.Property(x => x.Guid)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
该数据库在Guid列上没有任何标识列,并且该错误与Id列有关,但显然,这使EF在结果查询中对id值的处理变得混乱。
删除了上面的代码,对其进行了重新构建,并且一切正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.