【问题标题】:EF core 5 Update entity with Many to many ( the instance of entity type cannot be tracked)EF core 5 Update entity with Many to many(无法跟踪实体类型的实例)
【发布时间】:2021-04-23 02:28:01
【问题描述】:

Ad 和 Category 类之间存在多对多关系。

我有广告详情页面,我想在其中更新Ad。

在 UI 类别中实现为具有多个值的 Select2。

当我更新ad我得到错误类别的实例已经被跟踪。(实体类型的实例无法被跟踪,因为另一个实例具有相同的{'Id'} 的键值已被跟踪 )

这是我检索广告以显示在详细信息页面上的代码,也是更新广告的代码。

public async Task<Ad> GetById(int id)
        {
            return await _databaseContext.Ads.Include(x => x.SchoolLevels).Include(x => x.Categories).Include(x => x.Images).FirstOrDefaultAsync(x => x.Id == id);
        }


        public async Task<Ad> Update(Ad ad)
        {
            _databaseContext.Entry(ad).State = EntityState.Modified;

            _ = await _databaseContext.SaveChangesAsync();
            return ad;
        }

这似乎很常见。我有详细信息页面,在某些选择框中我必须选择多个值。

这是我的 UI 代码 (Blazor)

                    <div class="form-group">
                        <label>Categories</label>
                       
                        <Select2 TItem="Categories"
                                 TSource="List<Category>"
                                 IdSelector="@(i => i != null ? i.Id.ToString() : "")"
                                 TextSelector="i => i.Name"
                                 Datasource="Categories"
                                 Multiselect="true"
                                 Value="@Ad.Categories"
                                 GetElementById="(items, filter, token) => Task.FromResult(items.SingleOrDefault(i => i.Id.ToString().Equals(filter)))"
                                 FilterFunction="(items, filter, token) => Task.FromResult(items.Where(i => i.Name.ToLower().StartsWith(filter.ToLower())).ToList())">

                        </Select2>
                    </div>
 
                    </div>
                    <SaveButton IsSaving="IsSaving" />
 
                </EditForm> 

【问题讨论】:

    标签: asp.net entity-framework entity-framework-core blazor ef-core-5.0


    【解决方案1】:

    尝试将您的更新操作代码更改为此。您有一个错误,表明实例已被跟踪。这段代码会找到这个被跟踪的实例并更新它:

    public async Task<Ad> Update(Ad ad)
    {
            var existItem = await  _databaseContext.Set<Ad>().FindAsync(ad);
          //or you can try
            var existItem = await  _databaseContext.Set<Ad>()
                        .Where(i=>i.Id == ad.Id)  
                         .FirstOrDefaultAsync();
    
    
            if (existItem != null)
            {
            _databaseContext.Entry(existItem).CurrentValues.SetValues(ad);
            var result = await _databaseContext.SaveChangesAsync();
            if (result == 0)  ... error code;
            } else  ...erorr code
    
           return ad;
     }
    

    【讨论】:

    • 我会尝试,但你能详细说明它的作用吗?我知道我可以在分配新类别之前取消所有类别,但是当我这样做时,我会遇到无法在表 AdCategory(多对多表)中插入重复值的异常。这是有道理的,因为我已经在该表中有一对 Ad-Category
    • @VladoPandžić 你找到解决方案了吗?我遇到了同样的问题,更新我的实体时,我在多对多实体上收到重复键错误。
    • 在我的情况下,我将 dbcontext 服务恢复为默认的范围。它被设置为瞬态以修复一些其他问题并最终在这里带来错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 2022-01-11
    • 2019-10-28
    相关资源
    最近更新 更多