实体框架:更新具有 IEnumerable 属性的实体时出错。 'Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException'

     2023-03-31     27

关键词:

【中文标题】实体框架:更新具有 IEnumerable 属性的实体时出错。 \'Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException\'【英文标题】:Entity Framework: Error updating an Entity with IEnumerable property. 'Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException'实体框架:更新具有 IEnumerable 属性的实体时出错。 'Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException' 【发布时间】:2021-01-09 08:59:29 【问题描述】:

我正在 ASP.NET Core 中开发我的第一个 webapi。我有两个实体:

public class Event : Entity

    private ISet<Ticket> _tickets = new HashSet<Ticket>();
    public string Name  get; protected set; 
    public string Description  get; protected set; 
    public DateTime StartDate  get; protected set; 
    public DateTime EndDate  get; protected set; 
    public DateTime CreatedAt  get; protected set; 
    public DateTime UpdatedAt  get; protected set; 
    public IEnumerable<Ticket> Tickets => _tickets;

    //.....

     public void AddTickets(int amount, decimal price)
    
        var seating = _tickets.Count + 1;
        for (var i = 0; i < amount; i++)
        
            _tickets.Add(new Ticket(this, seating, price));
            seating++;
        
    
 

  public class Ticket : Entity

    public Guid EventId  get; protected set; 
    public decimal Price  get; protected set; 
    //... and other properties

当我尝试创建新活动并为其分配门票时:

public class EventController : Controller

   [HttpPost]
    public async Task<IActionResult> AddEvent([FromBody] CreateEventCommand createEventCommand)
    
        createEventCommand.Id = Guid.NewGuid();
        await _eventService.AddAsync(createEventCommand.Id,
            createEventCommand.Name,
            createEventCommand.Description,
            createEventCommand.StartDate,
            createEventCommand.EndDate);

        await _eventService.AddTicketAsync(createEventCommand.Tickets,
            createEventCommand.Price,
            createEventCommand.Id);

        return Created($"/events/createEventCommand.Name", null);
        
    
 
 
 public class EventService : IEventService
 
            public async Task AddAsync(Guid id, string name, string description, DateTime startDate, DateTime endDate)
    
        var @event = await _eventRepository.GetAsync(id);
        if(@event != null)
        
            throw new Exception($"Event with this id: @event.Id already exist");
        

        var eventToAdd = new Event(id, name, description, startDate, endDate);
        await _eventRepository.AddAsync(eventToAdd);
    

    public async Task AddTicketAsync(int amount, decimal price, Guid eventId)
    
        var @event = await _eventRepository.GetAsync(eventId);
        if (@event == null)
        
            throw new Exception($"Event with this id: @event.Id already exist");
        

        @event.AddTickets(amount, price);
        await _eventRepository.UpdateAsync(@event);

    
  

 public class EventRepository : IEventRepository
 
    public async Task AddAsync(Event @event)
    
        _context.Events.Add(@event);
        await _context.SaveChangesAsync();
    
    
     public async Task UpdateAsync(Event @event)
    
        _context.Events.Update(@event);
        await _context.SaveChangesAsync();
    
   

在Tickets表上执行的查询是

  UPDATE [Tickets] SET [EventId] = @p700, [Price] = @p701, [PurchasedAt] = @p702, [Seating] = @p703, [UserId] = @p704, [Username] = @p705
  WHERE [Id] = @p706;
  SELECT @@ROWCOUNT;

之后会抛出异常:

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded.

我的问题是:在这种情况下不应该是 INSERT 查询而不是 UPDATE 吗?在这种情况下并发问题的原因可能是什么?我是 .NET 的新手,一般来说是并发,如果有任何帮助,我将不胜感激。

【问题讨论】:

您可以将 Ticket.Id 属性配置为 ValueGeneratedNever [DatabaseGenerated(DatabaseGeneratedOption.None)] 您不是通过 context.Tickets.Add() 添加票证,而是将它们添加到 event.Tickets 集合中。所以它们没有设置为添加的实体状态。相反,它们在逻辑上未被跟踪。在这种情况下,更改跟踪器将未跟踪的实体视为已修改。 感谢您的评论。看起来你是对的。如果我在一个步骤中添加带有门票的事件(context.Events.AddAsync(//带有门票的事件)然后 SaveAsync()它工作正常。如果它按顺序发生:'添加事件>保存>更新事件实体使用票>保存'然后我得到一个错误。我该如何更改更改跟踪器的行为呢?通过添加:.UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll)) 到 AddDbContext 方法中的选项它不起作用。 我想我根据您的第一条评论找到了原因。我所有的实体都继承自带有构造函数的 Entity 基类:protected Entity() Id = Guid.NewGuid();当我删除 Id 生成时,它工作正常...... 我不确定这是否有意义,但看起来门票实体在生成时已经 Id != null 所以 EF 想要更新它们而不是插入新记录...跨度> 【参考方案1】:

在您的 AddTicketAsync 方法中,您检索 Event 对象的附加实体。

您应该能够通过调用 AddTickets 方法并在保存更改后对其进行更新。

 @event.AddTickets(amount, price);
 _eventRepository.your_context.SaveChangesAsync();

通过这种方式,您将保存更新后的事件实体的状态

您遇到并发错误,因为您正在尝试更新附加的实体。以下帖子可以帮助你How to update record using entity framework core?

【讨论】:

感谢您的回复。不幸的是它没有工作。仍然返回相同的错误... 你可以尝试分离你的 eventToAdd var entity = _context.Events.Add(@event); _context.detach(实体);等待 _context.SaveChangesAsync();

使用 AJAX 绑定时创建/更新后具有 IEnumerable 属性的 Kendo Grid 模型未正确更新

】使用AJAX绑定时创建/更新后具有IEnumerable属性的KendoGrid模型未正确更新【英文标题】:KendoGridmodelwithanIEnumerablepropertynotupdatingcorrectlyafterCreate/UpdatewhenusingAJAXbinding【发布时间】:2013-07-0323:06:34【问题描述】:我遇到了一个问题,... 查看详情

无法在实体框架中更新具有唯一约束索引的实体

】无法在实体框架中更新具有唯一约束索引的实体【英文标题】:Can\'tupdateentitywithuniqueconstraintindexinEntityFramework【发布时间】:2017-03-2006:28:28【问题描述】:我有一个实体Invoice,其中有1个Provider和许多ParticularFieldValues。在我的... 查看详情

实体框架代码首先用于具有属性集合的对象

】实体框架代码首先用于具有属性集合的对象【英文标题】:EntityFrameworkcodefirstforobjectwithcollectionofproperties【发布时间】:2020-06-3007:06:00【问题描述】:我将C#和.NETCore与MySql和EntityFramework一起使用。我有一个带有一组属性的对象... 查看详情

该属性必须是有效的实体类型,并且该属性应该具有非抽象的 getter 和 setter。实体框架 [重复]

】该属性必须是有效的实体类型,并且该属性应该具有非抽象的getter和setter。实体框架[重复]【英文标题】:Thepropertymustbeavalidentitytypeandthepropertyshouldhaveanon-abstractgetterandsetter.EntityFramework[duplicate]【发布时间】:2014-10-2503:30:51【问... 查看详情

如何在实体框架中查找具有指定日期范围列表的日期?

...018:38:59【问题描述】:我创建了一个包含日期范围的类的IEnumerable。该类如下所示:publicclassRange<T>whereT:structpublicTStartget;set;pu 查看详情

如何首先使用实体​​框架 5 代码删除具有导航属性的对象?

】如何首先使用实体​​框架5代码删除具有导航属性的对象?【英文标题】:HowcanIdeleteanobjectwithnavigationpropertywithentityframework5codefirst?【发布时间】:2012-10-1518:00:21【问题描述】:我首先使用的是EF5代码,并且我有2个相关实体App... 查看详情

使用在多个列上具有主键的实体框架更新数据库

】使用在多个列上具有主键的实体框架更新数据库【英文标题】:UpdateDatabaseusingEntityFrameworkhavingprimarykeyonmultipleColumns【发布时间】:2015-06-0616:08:57【问题描述】:以下是我得到的错误信息:存储更新、插入或删除语句影响了意... 查看详情

无法获取要更新实体框架中导航属性的关系

】无法获取要更新实体框架中导航属性的关系【英文标题】:Cannotgetrelationshiptoupdatefornavigationpropertiesinentityframework【发布时间】:2012-03-0718:11:24【问题描述】:我目前正在使用EF4.3和CodeFirst。我的对象的创建工作(通过我的视图-... 查看详情

使用实体框架更新数据库记录(延迟加载和虚拟属性)

】使用实体框架更新数据库记录(延迟加载和虚拟属性)【英文标题】:UpdatingdatabaserecordusingEntityFramework(lazyloadingandvirtualproperties)【发布时间】:2012-11-1316:31:07【问题描述】:我正在努力更新数据库中现有讲师的数据。每个讲师... 查看详情

使用具有实体框架的 Advantage 数据提供程序的连接字符串中无法识别的属性“CommType”

】使用具有实体框架的Advantage数据提供程序的连接字符串中无法识别的属性“CommType”【英文标题】:Unrecognizedproperty\'CommType\'inconnectionstringusingAdvantageDataProviderwithEntityFramework【发布时间】:2021-03-1814:37:09【问题描述】:我正在... 查看详情

更新映射到视图的实体框架实体

】更新映射到视图的实体框架实体【英文标题】:UpdatinganEntityFrameworkentitymappedtoaview【发布时间】:2012-05-1614:19:11【问题描述】:我正在尝试包含一些派生数据(在数据库中计算)在使用实体框架代码优先的实体中。为此,我创... 查看详情

Dapper.SimpleCRUD 插入/更新/获取失败并显示消息“实体必须具有至少一个 [Key] 属性”

】Dapper.SimpleCRUD插入/更新/获取失败并显示消息“实体必须具有至少一个[Key]属性”【英文标题】:Dapper.SimpleCRUDInsert/Update/Getfailswithmessage"Entitymusthaveatleastone[Key]property"【发布时间】:2015-10-2116:45:31【问题描述】:我是Dapper... 查看详情

实体框架 - 包括多个级别的属性

】实体框架-包括多个级别的属性【英文标题】:EntityFramework-IncludeMultipleLevelsofProperties【发布时间】:2012-06-0501:32:33【问题描述】:Include()方法对于对象列表非常有效。但是,如果我需要深入两层怎么办?例如,下面的方法将返... 查看详情

具有代码优先迁移的实体框架多个项目

】具有代码优先迁移的实体框架多个项目【英文标题】:EntityFrameworkmultipleprojectswithcodefirstmigrations【发布时间】:2014-04-0909:23:24【问题描述】:我有一个名为“Core”的类库项目,它定义了带有通用类属性的CoreContext:publicclassCore... 查看详情

NHibernate - 错误脱水属性值 - 更新实体

】NHibernate-错误脱水属性值-更新实体【英文标题】:NHibernate-Errordehydratingpropertyvalue-updatingentity【发布时间】:2019-02-1504:38:39【问题描述】:我在保存具有关联的实体时遇到问题。下面是我的代码,它给出了错误Fluent类继承自Fluen... 查看详情

在实体框架中交换具有唯一约束的值

】在实体框架中交换具有唯一约束的值【英文标题】:SwappingvalueswithuniqueconstraintinEntityFramework【发布时间】:2012-04-1910:56:25【问题描述】:我对名为Index的Navigations表的列有一个唯一约束。我有两个Navigation实体,我想交换它们的I... 查看详情

nhibernate-错误脱水属性值-更新实体

保存具有关联的实体时遇到问题。下面是我的代码,它给出了错误FluentClass继承自FluentMigrationpublicoverridevoidUp()//Updateyourchangestothedatabase{Create.Table("assinatura").WithColumn("id").AsInt32().Identity().PrimaryKey().WithColum 查看详情

通过反射动态修改 IEnumerable 属性

】通过反射动态修改IEnumerable属性【英文标题】:DynamicallymodifyinganIEnumerablepropertyviareflection【发布时间】:2020-12-1416:50:31【问题描述】:我有各种各样的类,它们具有实现IEnumerable的各种属性(例如IEnumerable&lt;string&gt;、IEnum... 查看详情