簡體   English   中英

EF:無法跟蹤實體類型X的實例,因為已經跟蹤了具有相同密鑰的此類型的另一個實例

[英]EF: The instance of entity type X cannot be tracked because another instance of this type with the same key is already being tracked

我在我的http請求中以Json格式發送一個User實體,如下所示:

POST http://localhost:52054/api/Authentication/DeleteAccessToken HTTP/1.1
Host: localhost:52054
Content-Type: application/json

{"id":1,"userName":"mnoureldin","accessToken":{"id":1,"token":"123ABC456EFG","userId":1}}

我的控制器(在EF核心中 )處理如下:

[HttpPost]
public IActionResult DeleteAccessToken([FromBody]User user)
{
    using (var Context = new UnitOfWork().Context)
    {
        var userEntity = Context.Users.Find(user.Id); // Get the real entity of the user received as json
        if (userEntity != null)
        {
            var accessTokenEntity = Context.AccessTokens.Find(userEntity.AccessToken.Id); // Find the entity of the accesstoken (I tried also directly by accessing the navigation property of user entity)
            Context.AccessTokens.Remove(accessTokenEntity);
            return Ok();
        }
        else
        {
            return Unauthorized();
        }
    }
}

但行Context.AccessTokens.Remove(accessTokenEntity); 拋出此異常:

Microsoft.EntityFrameworkCore.dll中出現“System.InvalidOperationException”類型的異常,但未在用戶代碼中處理

附加信息:無法跟蹤實體類型“AccessToken”的實例,因為已經跟蹤了具有相同密鑰的此類型的另一個實例。 添加新實體時,對於大多數鍵類型,如果未設置任何鍵,則將創建唯一的臨時鍵值(即,如果為鍵屬性指定了其類型的默認值)。 如果要為新實體顯式設置鍵值,請確保它們不會與現有實體或為其他新實體生成的臨時值發生沖突。 附加現有實體時,請確保只有一個具有給定鍵值的實體實例附加到上下文。

我還嘗試直接從userEntity訪問AccessToken導航屬性,但具有相同的異常。

這是我的UnitOfWork初始化:

public UnitOfWork()
{
    // Configure EF connection
    var optionsBuilder = new DbContextOptionsBuilder<CustomDbContext>();
    optionsBuilder
        .UseMySQL(@"server=192.168.1.35; port=3306; sslmode=none;
                    userid=root;
                    pwd=P@ssword;
                    database=dotnet;");

    Context = new CustomDbContext(optionsBuilder.Options);

    // Configure data loading method to explicit
    Context.AccessTokens.Load();
}

我的CustomBdContext:

public class CustomDbContext : DbContext
{
    // Tell EF to map the entities to tables
    public DbSet<User> Users { get; set; }
    public DbSet<AccessToken> AccessTokens { get; set; }

    public CustomDbContext(DbContextOptions options) : base(options)
    {
    }
}

我有以下簡單的數據模型與一對一的關系:

User ----- AccessToken

用戶:

public class User
{
    public int Id { get; set; }
    public string UserName { get; set; }

    public virtual AccessToken AccessToken { get; set; }
}

的accessToken:

public class AccessToken
{
    public int Id { get; set; }
    public string Token { get; set; }

    [ForeignKey("User"), Required]
    public int UserId { get; set; }
    public virtual User User { get; set; }
}

有人可以幫我解決這個問題嗎? 我不明白到底發生了什么......

看來EF已經在跟蹤user和其中的AccessToken 因此,讓我們嘗試避免獲取同一實體的另一個實例並重用已經跟蹤過的實例。

嘗試

[HttpPost]
public IActionResult DeleteAccessToken([FromBody]User user)
{
    // Requires System.Linq
    if (Context.Users.Any(u => u.Id == user.Id))
    {
        var accessTokenEntity = Context.AccessTokens.Find(user.AccessToken.Id); // Find the entity of the accesstoken (I tried also directly by accessing the navigation property of user entity)
        Context.AccessTokens.Remove(accessTokenEntity);

        // NOTE: You re not saving?
        return Ok();
    }
    else
    {
        return Unauthorized();
    }
}

或者嘗試:

[HttpPost]
public IActionResult DeleteAccessToken([FromBody]User user)
{
    if (Context.Users.Any(u => u.Id == user.Id))
    {
        Context.AccessTokens.Remove(user.AccessToken);
        return Ok();
    }
    else
    {
        return Unauthorized();
    }
}

嘗試替換此行:

var accessTokenEntity = Context.AccessTokens.Find(userEntity.AccessToken.Id);

至:

var accessTokenEntity = Context.AccessTokens.AsNoTracking().Find(userEntity.AccessToken.Id);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM