我正在使用EntityFrameworkCore(AspNetCore),我试图从ajax调用更新模型(Pack)。在我的更新中,我想插入负面的实体 (或0)id并更新具有正常id的实体。我不知道它是好还是坏,所以如果你有一些提示。
以下是一些模型:
public class Pack
{
[Key]
public int PackId { get; set; }
public string PackName { get; set; }
public ICollection<CardPack> CardPacks { get; set; }
}
public class CardPack
{
[Key]
[ForeignKey("Card")]
public int CardId { get; set; }
[Key]
[ForeignKey("Pack")]
public int PackId { get; set; }
public Card Card { get; set; }
public Pack Pack { get; set; }
}
public class Card
{
[Key]
public int CardId { get; set; }
public ICollection<FaceCard> FaceCards { get; set; }
}
复合pk的我的Db上下文:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
foreach (var relationship in
modelBuilder.Model.GetEntityTypes().SelectMany(e =>
e.GetForeignKeys()))
{
relationship.DeleteBehavior = DeleteBehavior.Restrict;
}
modelBuilder.Entity<CardPack>(entity =>
{
entity.HasKey(t => new { t.CardId, t.PackId });
});
}
这是更新方法。
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SavePackWithAllCards([FromBody] Pack pack)
{
// I don't use this pack for the example, i create a new one
var newPack = new Pack
{
PackName = "test"
};
_context.Add(newPack);
await _context.SaveChangesAsync();
var cardpacks = new List<CardPack>();
var cardpack = new CardPack
{
CardId = 0, // random negative number
PackId = 0,
Card = new Card
{
CardId = 0
}
};
cardpacks.Add(cardpack);
newPack.CardPacks = cardpacks;
try
{
_context.Packs.Update(newPack);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
return RedirectToAction("error", "home");
}
}
我在对象包中的例子
我遇到以下错误。
{Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: The column name 'PCK_ID' is specified more than once in the SET clause or column list of an INSERT. A column cannot be assigned more than one value in the same clause. Modify the clause to make sure that a column is updated only once. If this statement updates or inserts columns into a view, column aliasing can conceal the duplication in your code.
at System.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__107_0(Task`1 result)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.<ExecuteAsync>d__26.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.<ExecuteAsync>d__32.MoveNext()
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.<ExecuteAsync>d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.<ExecuteAsync>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerExecutionStrategy.<ExecuteAsync>d__6`2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<SaveChangesAsync>d__54.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<SaveChangesAsync>d__52.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.EntityFrameworkCore.DbContext.<SaveChangesAsync>d__35.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at FicheTips.Web.Controllers.PackController.<SavePackWithAllCards>d__13.MoveNext() in C:\VS2017\Projects\FicheTips\FicheTips\FicheTips.Web\Controllers\PackController.cs:line 355}