我有一個 WebAPI 來使用 Pokemon 公共 API。我使用 .NET 5.0 和 EF 5.0 構建了它。一切都很順利,直到我添加了將 API 使用到控制器的邏輯并嘗試將更改保存到背景關系中。
當我運行 _context.SaveChangesAsync() 我有一個錯誤說:
“當 IDENTITY_INSERT 設定為 OFF 時,無法在表 'PokemonDtos' 中插入標識列的顯式值。”
問題是,一切都是由 EF 創建的。我還沒有創建任何表。我使用 json2csharp 和 jsonformatter 創建的用于反序列化 json 的類,因此我可以理解如何正確反序列化它們。
我究竟做錯了什么?代碼似乎一切正常,我只是迷失了這個資料庫問題。資料庫也被創建,并且表在那里。
PokemonDtoController.cs
{
[Route("api/[controller]")]
[ApiController]
public class PokemonDtoesController : ControllerBase
{
private readonly DataContext _context;
private PokemonDto currPoke = null;
public PokemonDtoesController(DataContext context)
{
_context = context;
}
// GET: api/PokemonDtoes
[HttpGet]
public async Task<ActionResult<IEnumerable<PokemonDto>>> Get_pokemons()
{
int limit = 3;
string url = $"https://pokeapi.co/api/v2/pokemon/?ffset={limit}&limit={limit}";
string json = string.Empty;
using (HttpClient _client = new HttpClient())
{
_client.BaseAddress = new Uri(url);
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await _client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
json = await response.Content.ReadAsStringAsync();
BaseResults myDeserializedClass = JsonConvert.DeserializeObject<BaseResults>(json);
if (myDeserializedClass != null)
{
foreach (var result in myDeserializedClass.results)
{
using (HttpClient insideclient = new HttpClient())
{
insideclient.BaseAddress = new Uri(result.url);
response = await insideclient.GetAsync(result.url);
if (response.IsSuccessStatusCode)
{
json = await response.Content.ReadAsStringAsync();
//AbilitiesRoot currPokeAbilities = JsonConvert.DeserializeObject<AbilitiesRoot>(json);
currPoke = JsonConvert.DeserializeObject<PokemonDto>(json);
if (currPoke != null)
{
try
{
_context.Add(currPoke);
await _context.SaveChangesAsync();
// _context.SaveChanges();
}
catch(Exception e)
{
return null;
}
}
}
}
}
}
}
}
return await _context.PokemonDtos.ToListAsync();
}
資料背景關系.cs
public class DataContext : DbContext
{
protected readonly IConfiguration Configuration;
public DataContext(IConfiguration configuration)
{
this.Configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnectionString"));
}
public DbSet<PokemonDto> PokemonDtos { get; set; }
}
也許我也應該列出我的步驟。創建所有代碼后,我運行以下命令:
dotnet ef 遷移添加 PokeMigrations3 dotnet ef 資料庫更新
uj5u.com熱心網友回復:
我認為有2個選擇。
選項 1:
Id 是自動增量,但您插入的是帶有SET IDENTITY_INSERT [TableName] OFF
. 之后,您忘記了SET IDENTITY_INSERT [TableName] ON
從 MSSQL 執行。
選項 2:
您將 Guid 用于 Id 欄位,但在插入時未生成新的 Guid。您可以使用,也可以使用someEntity.Id = Guid.NewGuid();
以下 2 種方式進行操作。
方式一:
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
方式2:
您必須識別抽象(is-a)/介面(可以做)物體,其他物體必須繼承這個抽象物體。
override Task<int> SaveChangesAsync(..)/override int SaveChanges(..)
{
var insertingEntities = ChangeTracker.Entries()
.Where(e => e.Entity is BaseEntity && (e.State == EntityState.Added));
foreach (var entry in insertingEntities)
{
if (entry.Entity is BaseEntity entity)
{
if (entry.State == EntityState.Added)
{
entity.Id = Guid.NewGuid();
}
}
}
return base.SaveChangesAsync(..)/base.SaveChanges();
}
uj5u.com熱心網友回復:
我相信您需要自動生成Id
屬性,PokemonDto
因為資料庫未設定為自動生成它。
要使其自動生成此主鍵屬性,您可以使用該屬性DatabaseGeneratedAttribute
強制資料庫自動生成鍵:
public class PokemonDto
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public Guid PokemonDtoId { get; set; }
// ...
}
另一種方法是在將更改保存到資料庫之前分配 id 屬性。
try
{
currPoke.MyIdProperty = Guid.NewGuid(); // or assign to whatever type it is
_context.Add(currPoke);
await _context.SaveChangesAsync();
}
uj5u.com熱心網友回復:
您要反序列化的 Json 很可能有一個名為 id 的欄位。這是設定您的 PokemonDto 物體的 Id 屬性,這是您的資料庫不允許的,因為它使用自動增量。
一個快速的解決方法是將您的 PokemonDto 的 Id 屬性更改為 PokemonDtoId,這將確保它不會被 json 值設定。
另一種選擇是在 PokemonDto 類的 id 屬性上方使用 JsonIgnore 屬性。https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/ignore-properties?pivots=dotnet-6-0。
如果您想使用從您的 json 物件發送的 Id,那么您可以查看以下答案: Insert new entity with EF Core with a manual assignment Id
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/519414.html