C# 如果Azure表存储服务上下文遇到一个错误,它将继续抛出相同的错误

C# 如果Azure表存储服务上下文遇到一个错误,它将继续抛出相同的错误,c#,iis,azure,azure-storage,azure-table-storage,C#,Iis,Azure,Azure Storage,Azure Table Storage,当我尝试在azure表存储上更新或创建实体时,它有时会抛出一个错误,如“实体已存在”或“一个请求输入超出范围”,之后,如果我尝试在该表上创建或更新其他实体,它会继续抛出相同的错误。输入没有问题,就好像我重新启动iis服务器,它又开始工作一样。我不知道为什么会这样 我尝试了不同的SaveChangesOptions,包括“ContinueOnError”,但在遇到一个错误后,表服务上下文在所有进一步的更新/创建时继续抛出错误 public class AudioRecordRepository :

当我尝试在azure表存储上更新或创建实体时,它有时会抛出一个错误,如“实体已存在”或“一个请求输入超出范围”,之后,如果我尝试在该表上创建或更新其他实体,它会继续抛出相同的错误。输入没有问题,就好像我重新启动iis服务器,它又开始工作一样。我不知道为什么会这样

我尝试了不同的SaveChangesOptions,包括“ContinueOnError”,但在遇到一个错误后,表服务上下文在所有进一步的更新/创建时继续抛出错误

public class AudioRecordRepository : Repository<PersistedAudioRecord>, IAudioRecordRepository
{
    private TableStorageServiceContext<PersistedAudioRecord> audioRecordServiceContext;
    private CloudStorageAccount cloudStorageAccount;

    public AudioRecordRepository(IServiceContext<PersistedAudioRecord> serviceContext)
        : base(serviceContext)
    {
        if (RoleEnvironment.IsAvailable)
            cloudStorageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("StorageConnectionString"));
        else
            cloudStorageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]);

        audioRecordServiceContext = new TableStorageServiceContext<PersistedAudioRecord>(TableNames.AudioRecord, cloudStorageAccount.TableEndpoint.ToString(), cloudStorageAccount.Credentials) { IgnoreResourceNotFoundException = true };

    }

    public bool CreateRecord(PersistedAudioRecord record)
    {
        this.audioRecordServiceContext.Create(record);
        this.audioRecordServiceContext.SaveChangesWithRetries(SaveChangesOptions.ContinueOnError);

        return true;
    }
}
下面是我如何创建表存储服务上下文的代码

请让我知道问题可能是什么,这对我来说是一个巨大的障碍,因为如果表服务上下文只遇到一个错误,我的应用程序中的主要功能将停止工作

public class AudioRecordRepository : Repository<PersistedAudioRecord>, IAudioRecordRepository
{
    private TableStorageServiceContext<PersistedAudioRecord> audioRecordServiceContext;
    private CloudStorageAccount cloudStorageAccount;

    public AudioRecordRepository(IServiceContext<PersistedAudioRecord> serviceContext)
        : base(serviceContext)
    {
        if (RoleEnvironment.IsAvailable)
            cloudStorageAccount = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("StorageConnectionString"));
        else
            cloudStorageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]);

        audioRecordServiceContext = new TableStorageServiceContext<PersistedAudioRecord>(TableNames.AudioRecord, cloudStorageAccount.TableEndpoint.ToString(), cloudStorageAccount.Credentials) { IgnoreResourceNotFoundException = true };

    }

    public bool CreateRecord(PersistedAudioRecord record)
    {
        this.audioRecordServiceContext.Create(record);
        this.audioRecordServiceContext.SaveChangesWithRetries(SaveChangesOptions.ContinueOnError);

        return true;
    }
}
公共类AudioRecordRepository:Repository,IAAudioRecordRepository
{
私有表存储ServiceContext audioRecordServiceContext;
私有CloudStorageAccount CloudStorageAccount;
公共录音库(IServiceContext serviceContext)
:base(serviceContext)
{
如果(RoleEnvironment.IsAvailable)
cloudStorageAccount=cloudStorageAccount.Parse(roleenEnvironment.GetConfigurationSettingValue(“StorageConnectionString”);
其他的
cloudStorageAccount=cloudStorageAccount.Parse(ConfigurationManager.AppSettings[“StorageConnectionString]”);
audioRecordServiceContext=新表存储ServiceContext(TableNames.AudioRecord,cloudStorageAccount.TableEndpoint.ToString(),cloudStorageAccount.Credentials){IgnoreResourceNotFoundException=true};
}
公共bool CreateRecord(PersistedAudioRecord记录)
{
此.audioRecordServiceContext.Create(记录);
this.audioRecordServiceContext.SaveChangesWithRetries(SaveChangesOptions.ContinueOnError);
返回true;
}
}

似乎包含实体的上下文(audioRecordServiceContext)是在类级别声明的,并且不清楚是否/何时将其清除

表存储上下文遵循“工作单元”设计模式。它们被设计用于跟踪实体。如果您在上下文中添加了一个“坏”实体并试图持久化,那么很明显会出现错误。然而,您需要注意的是,您的上下文并没有丢弃坏的实体。它仍然在跟踪它,它仍然认为你想保存它。因此,下一个SaveChanges调用将再次尝试保存它

建议:在您的上下文周围放置一个“using”语句,仅当您需要保存实体时才在函数中声明它-不要让它位于类级别-除非您有需要它的特定用例。但如果您这样做了,那么请确保将失败的实体从上下文对象中拉出(您可以通过检查上下文对象的Entities集合手动执行此操作)


HTH

您可以为给定的表重新创建TableServiceContext对象

TableServiceContext tableServiceContext = tableClient.GetDataServiceContext();

升级到存储库2,它更好,支持更多的查询,并且有相当快的启动。

你是否考虑迁移到Azure SDK的新版本?它新的访问服务的方式简单直观。这是一个链接,如果您想迁移,我已经编辑了我的代码。我在类的构造函数中声明服务上下文。并且我在该类的方法中访问服务上下文。因此,当我从控制器调用这些方法时,我猜服务上下文没有被清除。一种方法是在抛出任何错误时分离实体?这样行吗?还有其他方法吗?我正在类中的多个方法中保存实体,因此我不希望在这些方法中的每个方法中创建单独的服务上下文。创建上下文对象实际上不会影响性能。它不像一个资源耗尽的SQL连接。表上下文只是一个具有URL并跟踪实体的对象。如果您需要在函数调用之间共享上下文中的实体,那么您需要做出选择——您应该拥有所有权并清理坏的实体。否则,每次都实例化新的上下文,实体跟踪将是功能特定的。非常感谢,这很有帮助!!