我已经搜索了相关问题,但是找不到解决方案。我有一个asp.net核心Web应用程序,在其中选择一行并编辑记录。它在弹出窗口中显示表单,其中包含相关数据以及ID(也已隐藏)。这是实体:
public class Sender
{
public long Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string ContactPerson { get; set; }
public string ContactEmail { get; set; }
public IEnumerable<Document> Documents { get; set; }
}
我使用存储库模式来处理数据操作:
public class DataSender : IRepositorySender
{
private DataContext DataContext;
public DataSender(DataContext Context)
{
DataContext = Context;
}
public IEnumerable<Sender> Senders => DataContext.Senders;
public Sender GetSender(long SenderId)
{
return DataContext.Senders.Find(SenderId);
}
public void AddSender(Sender Sender)
{
DataContext.Senders.Add(Sender);
DataContext.SaveChanges();
}
public void UpdateSender(Sender Sender)
{
DataContext.Senders.Update(Sender);
DataContext.SaveChanges();
}
public void DeleteSender(Sender Sender)
{
}
}
这是相关的动作:
[Route("{SenderId}")]
public IActionResult UpdateSender(long SenderId)
{
ViewBag.Mode = "update";
return PartialView("Sender", SenderRepository.GetSender(SenderId));
}
[HttpPost("UpdateSender")]
public IActionResult UpdateSender(Sender Sender)
{
SenderRepository.UpdateSender(Sender);
return RedirectToAction(nameof(List));
}
我在弹出窗口中获得了所需的数据,保存了更改,但是EF插入了一条新记录,而不是对其进行更新。为什么?
编辑:
这是更新视图:
@model Sender
<form asp-action=@(ViewBag.Mode == "new" ? "AddSender" : "UpdateSender") asp-controller="Sender" method="post">
@using (Html.DevExtreme().ValidationGroup())
{
@(Html.DevExtreme().Form<Sender>()
.ID("form")
.ColCount(1)
.Items(items => {
items.AddSimpleFor(m => Model.Id).Visible(false);
items.AddSimpleFor(m => Model.Name);
items.AddSimpleFor(m => Model.Address);
items.AddSimpleFor(m => Model.ContactPerson);
items.AddSimpleFor(m => Model.ContactEmail);
items.AddGroup().Items(groupItem => groupItem.AddSimple().Template(
@<text>
<div style="text-align: right">
@(Html.DevExtreme().Button().ID("save").Text("Mentés").Width(100).Type(ButtonType.Success).UseSubmitBehavior(true))
@(Html.DevExtreme().Button().ID("cancel").Text("Mégsem").Width(100).Type(ButtonType.Normal).OnClick("close_onClick"))
</div>
</text>));
})
.LabelLocation(FormLabelLocation.Top)
.FormData(Model)
)
}
</form>
编辑2: 这是调试窗口的输出。对您有用吗?我看到,EF需要一个新的ID,并将记录插入数据库中。关键点在于,为什么ID为0,为什么EF或webapp(模型绑定)无法识别实体已经具有有效的ID值。
Microsoft.EntityFrameworkCore.ChangeTracking: Debug: 'DataContext' generated temporary value '-9223372036854774805' for the 'Id' property of new 'Sender' entity.
Microsoft.EntityFrameworkCore.ChangeTracking: Debug: Context 'DataContext' started tracking 'Sender' entity with key '{Id: -9223372036854774805}'.
Microsoft.EntityFrameworkCore.ChangeTracking: Debug: DetectChanges starting for 'DataContext'.
Microsoft.EntityFrameworkCore.ChangeTracking: Debug: DetectChanges completed for 'DataContext'.
Microsoft.EntityFrameworkCore.Database.Transaction: Debug: Beginning transaction with isolation level 'Unspecified'.
Microsoft.EntityFrameworkCore.Database.Transaction: Debug: Began transaction with isolation level 'ReadCommitted'.
Microsoft.EntityFrameworkCore.Database.Command: Debug: Creating DbCommand for 'ExecuteReader'.
Microsoft.EntityFrameworkCore.Database.Command: Debug: Created DbCommand for 'ExecuteReader' (3ms).
Microsoft.EntityFrameworkCore.Database.Command: Debug: Executing DbCommand [Parameters=[@p0='Teszt cím' (Nullable = false) (Size = 4000), @p1='teszt@teszt.com' (Nullable = false) (Size = 4000), @p2='Teszt név' (Nullable = false) (Size = 4000), @p3='Teszt cég' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
INSERT INTO [Senders] ([Address], [ContactEmail], [ContactPerson], [Name])
VALUES (@p0, @p1, @p2, @p3);
SELECT [Id]
FROM [Senders]
WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();
Microsoft.EntityFrameworkCore.ChangeTracking: Debug: Foreign key property 'Sender.Id' detected as changed from '-9223372036854774805' to '71' for entity with key '{Id: 71}'.
Microsoft.EntityFrameworkCore.Database.Command: Debug: A data reader was disposed.
Microsoft.EntityFrameworkCore.Database.Transaction: Debug: Committing transaction.
Microsoft.EntityFrameworkCore.Database.Transaction: Debug: Committing transaction.
Microsoft.EntityFrameworkCore.Database.Transaction: Debug: Disposing transaction.
Microsoft.EntityFrameworkCore.ChangeTracking: Debug: The 'Sender' entity with key '{Id: 71}' tracked by 'DataContext' changed from 'Added' to 'Unchanged'.
答案 0 :(得分:0)
我看到了,没有看到完整的流程就无济于事,您可以尝试使用Debug Logger并查看更改跟踪
services.AddDbContext<ApplicationDbContext>(options => options
.UseLoggerFactory(MyLoggerFactory)
.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")).EnableSensitiveDataLogging());
public static readonly ILoggerFactory MyLoggerFactory
= LoggerFactory.Create(builder =>
{
builder
.AddFilter((category, level) =>
(category == DbLoggerCategory.ChangeTracking.Name |
category == DbLoggerCategory.Database.Transaction.Name |
category == DbLoggerCategory.Database.Command.Name)
&& level == LogLevel.Debug)
.AddDebug();
});
这将产生带有Entityframework Core发出的Change Tracking,Transaction和Command以及数据传递的调试日志,尤其要注意changetracking,因为它将识别您的对象是要添加还是更新
编辑1 调试:'DataContext'为new的'Id'属性生成了临时值'-9223372036854774805'
我看到Id没有价值,在您的控制器和savechanges之间有一些被删除的地方,您使用的是任何类型的映射,还是检查您的存储库,使用f11进行调试并查看丢失的地方>
答案 1 :(得分:0)
问题是,Id字段的可见性设置为false,这导致默认值分别为0。不绑定ID字段。我添加了一个@Html.HiddenFor(m => Model.Id)
字段,现在它可以正常工作了。