如何更新 aspnetboilerplate 中的实体?

How to update the entity in aspnetboilerplate?

我想更新数据库中的一个实体。我使用 aspnetboilerplate 模板项目。我在应用层有一个方法UpdateAsset

public async Task UpdateAsset(UpdateAssetInput input)
    {
        var asset = ObjectMapper.Map<Asset>(input.Asset);
        asset.Domain = asset.Domain.ToLowerInvariant();

        // Update Twitter Id
        var twitterName = input.Asset.SocialAccounts?.TwitterInfo?.Name;
        if (twitterName != null)
        {
            var twitterId = await _twitterActivityManager.GetTwitterIdByTwitterName(twitterName);
            if (twitterId != null)
            {
                input.Asset.SocialAccounts.TwitterInfo.Id = twitterId;
            }
        }

        asset.SetData<SocialAccounts>(AssetExtensionData.SocialAccounts, input.Asset.SocialAccounts);
        var connectedAsset = await _assetManager.GetAsset(input.Asset.LockedPositionInfo.ConnectedAssetId);
        if (connectedAsset != null)
        {
            input.Asset.LockedPositionInfo.ConnectedAssetUnit = connectedAsset.Unit;
        }
        asset.SetData<LockedPositionInfo>(AssetExtensionData.LockedPositionInfo, input.Asset.LockedPositionInfo);
        asset.SetData(AssetExtensionData.WithdrawalApiInfo, input.Asset.WithdrawalApiInfo);
        await _assetManager.UpdateAsset(asset);
    }

更新资产输入:

public class UpdateAssetInput
{
    public AssetDto Asset { get; set; }
}

AssetDto:

[AutoMap(typeof(Asset))]
public class AssetDto : AuditedEntityDto<string>
{
    public const int SYMBOL_LENGTH = 10;

    [Required]
    [MaxLength(SYMBOL_LENGTH)]
    public new string Id { get; set; }

    [Required]
    public string Name { get; set; }

    public string Description { get; set; }

    public string Website { get; set; }

    [Required]
    public string Domain { get; set; }

    public string Logo { get; set; }

    public string Organization { get; set; }

    public string Unit { get; set; }

    public SocialAccounts SocialAccounts { get; set; }

    public LockedPositionInfo LockedPositionInfo { get; set; }

    public WithdrawalApiInfo WithdrawalApiInfo { get; set; }


    public decimal TotalAmount { get; set; }

    public decimal Price { get; set; }

    public bool IsDisable { get; set; } = false;
}

AssetManager 中的 UpdateAsset:

public async Task UpdateAsset(Asset asset)
    {
        try
        {
            await _assetRepository.UpdateAsync(asset);
        }
        catch (Exception e)
        {
            Logger.Error(e.Message, e);
            throw new UserFriendlyException(L("AssetUpdateFailed"), asset.Name);
        }
    }

当我在前端调用应用层的UpdateAsset时,出现异常:

System.InvalidOperationException: 'The instance of entity type 'Asset' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. 

那么如何解决问题呢?

通常情况下,当我们更新资产实体时,我们会做以下3个步骤:

  1. 从数据库中获取资产实体
  2. 为资产实体设置更新值
  3. 更新资产实体

根据您的错误信息,您可能会两次从数据库中获取资产实体

  1. 从数据库中获取资产 1 实体 - 已跟踪
  2. 从数据库获取资产 2 实体 - 跟踪
  3. 将更新值设置为 asset2 实体
  4. 更新 asset2 实体

请检查您是否有以上代码片段