簡體   English   中英

InsertAndGetIdAsync-無法為標識列插入顯式值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM