none
ResourceNotfound Exception when trying to delete objects from an Azure Table

    Question

  • Here is what I am trying to do:

    I call a method that creates the table:

     

    private void _createPolygonTable(CloudStorageAccount

    account)

    {

     

    CloudTableClient.CreateTablesFromModel(typeof(PolygonDataContext

    ),account.TableEndpoint.AbsoluteUri, account.Credentials);

     

    var polygonCtxt = new PolygonDataContext

    (account.TableEndpoint.ToString(), account.Credentials);

    polygonCtxt.EmptyTable();

    }

    

    if I hover on polygonCtxt during debugging it shows

    base {System.Data.Services.Client.DataServiceQuery} = {http://127.0.0.1:10002/devstoreaccount1/Polygons}

    I guess this means the table named Polygons has been created (?)

    The method EmptyTable looks like the following:

    public void EmptyTable()

    {

     

    foreach (var polygon in this.Polygon)

    {

     

    try

    {

     

     

    this

    .DeleteObject(polygon);

     

     

    this

    .SaveChanges();

    }

     

     

    catch (Exception

    ) { }

    }

    The foreach statement throws resourcenotfound exception. resourcenotfound is inner exception of DataServiceQueryException was unhandled.

    I can easily replace Exception with DataServiceQueryException and catch this exception but I wonder if that exception is fine at this location. Should it not run without throwing that exception? Thank you for your help in advance.

    

    Regards,

    Dinesh Agarwal

    Tuesday, April 5, 2011 2:19 AM

Answers

  • I am looking inside your code. I dont really understand to it, but from my view I see some possible code issues.

    Everytime your app is starting(means: everytime a new instance is starting or was recycled) you are trying to create table for context......can be problem with existence of tables that you are trying to recreate? Take a look at and read remarks carefully http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storageclient.cloudtableclient.createtablesfrommodel.aspx

    It's now recommended that you use the CreateTable or CreateTableIfNotExist method to create a table, rather than CreateTablesFromModel. It is not necessary to create a custom class that is derived from TableServiceContext in order to work with Table service data.

    Can be problem there????

    Try this code in webrole.cs:

     

           private void _createPolygonTable(CloudStorageAccount account)

            {

                CloudTableClient tableClient = account.CreateCloudTableClient(); // create table client

                if (!tableClient.CreateTableIfNotExist(PolygonDataContext.TableName)) // create table if not exists with bool value returned, TableName is const for this context ;-)

                { // if teble exists then delete entities in there

                    PolygonDataContext polygonCtxt = new PolygonDataContext(account.TableEndpoint.ToString(), account.Credentials);

                    polygonCtxt.EmptyTable(); 

                }                  

            }

    After all I still miss the point of deleting all content in context table.

     


    • Edited by cloudikka Wednesday, April 6, 2011 2:33 PM updated code comment
    • Marked as answer by dinwal_pdc_guy Wednesday, April 6, 2011 6:51 PM
    Wednesday, April 6, 2011 2:28 PM

All replies

  • Try something as this. Check if it works for you:


    private PolygonDataContext context;

            public void DeletePolygonTableEntries()
            {
                try
                {
                    var result = from g in this.context.Polygon                            
                                 select g;

                    foreach (Polygon polygonEntries in result)
                    {
                        context.DeleteObject(polygonEntries);
                        context.SaveChanges();
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

    -----------------------------------------------------------------------------------------------------------------------------------------------
    Regards,
    Anirudha
    (If this post answers your question, please mark it as an answer. OR If it is helpful, then vote it as helpful.)
    -----------------------------------------------------------------------------------------------------------------------------------------------

    Tuesday, April 5, 2011 12:05 PM
  • In addition to what Anirudha has above, a ResourceNotFound exception should be expected when a resource does not exist; unless you use the following flag to ignore it:

    DataServiceContext svc = tableClient.GetDataServiceContext();
    svc.IgnoreResourceNotFoundException = true;
    If you choose to handle the exception - in this scenario, you can log info and ignore the exception since you were anyway trying to delete it.

    Btw, if clearing entities is a pri 0 scenario then think in terms of creating a new table (with new name) each time and deleting the old table. This approach requires just one request to delete all entities. The reason for proposing a new table name is because recreating the same table can take time. A couple of approaches which I have seen being used are:

    1> create a table with self discoverable names like suffix of day/month etc.

    2> or use a config table to indicate the table name being used.

    Thanks,

    Jai

    Tuesday, April 5, 2011 1:56 PM
  • Little tuning from financial view. Put save chances after foreach statement. You will not spend transaction per each delete. One batch(one transaction) is able for up to 100 items in same table and same partition.

     

    foreach (Polygon polygonEntries in result)
                    {
                        context.DeleteObject(polygonEntries);
                    }

      context.SaveChanges(SaveChangesOptions.Batch);

     

    Post about it with some code for inspiration  http://blogs.msdn.com/b/windowsazurestorage/archive/2010/04/22/savechangeswithretries-and-batch-option.aspx

     

    Additional information about Entity group Transactions here http://msdn.microsoft.com/en-us/library/dd894038.aspx

    Tuesday, April 5, 2011 6:48 PM
  • Thank you everyone for your inputs. I figured that the error is with the context creation. I create it by calling:

     

    private void _createPolygonTable(CloudStorageAccount

     

    CloudTableClient.CreateTablesFromModel(typeof(PolygonDataContext

     

    var polygonCtxt = new PolygonDataContext

     


    Dinesh Agarwal

    (account.TableEndpoint.ToString(), account.Credentials);

     

    polygonCtxt.EmptyTable();

    }

    After the polygonCtxt creation when I check polygonCtxt and it seems it has the ResourceNotFound exception. I can not find what is wrong or where is the main problem.I have just started working with Azure as well as C# so please ignore my naivety. Thank you all for your help.

     

    ),account.TableEndpoint.AbsoluteUri, account.Credentials);

     

     

    account)

     

    {

     

    Wednesday, April 6, 2011 4:43 AM
  • I am looking inside your code. I dont really understand to it, but from my view I see some possible code issues.

    Everytime your app is starting(means: everytime a new instance is starting or was recycled) you are trying to create table for context......can be problem with existence of tables that you are trying to recreate? Take a look at and read remarks carefully http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storageclient.cloudtableclient.createtablesfrommodel.aspx

    It's now recommended that you use the CreateTable or CreateTableIfNotExist method to create a table, rather than CreateTablesFromModel. It is not necessary to create a custom class that is derived from TableServiceContext in order to work with Table service data.

    Can be problem there????

    Try this code in webrole.cs:

     

           private void _createPolygonTable(CloudStorageAccount account)

            {

                CloudTableClient tableClient = account.CreateCloudTableClient(); // create table client

                if (!tableClient.CreateTableIfNotExist(PolygonDataContext.TableName)) // create table if not exists with bool value returned, TableName is const for this context ;-)

                { // if teble exists then delete entities in there

                    PolygonDataContext polygonCtxt = new PolygonDataContext(account.TableEndpoint.ToString(), account.Credentials);

                    polygonCtxt.EmptyTable(); 

                }                  

            }

    After all I still miss the point of deleting all content in context table.

     


    • Edited by cloudikka Wednesday, April 6, 2011 2:33 PM updated code comment
    • Marked as answer by dinwal_pdc_guy Wednesday, April 6, 2011 6:51 PM
    Wednesday, April 6, 2011 2:28 PM
  • Rename the table name as Polygon or your property that returns IQueryable<PolygonEntity> as Polygons. Either one should work. I would also recommend what Peter said - do not use CreateTablesFromDataModel but use the explicit CreateTableIfNotExists.

    The other thing I noticed was you are calling SaveChanges for each entity. If the Partitionkey is the same for all entities being deleted, you could use Entity Group Transactions by using SaveChanges(SaveChangesOptions.Batch) with maximum of 100 entities at a time.

    Thanks,
    Jai

    Wednesday, April 6, 2011 3:07 PM
  • I am looking inside your code. I dont really understand to it, but from my view I see some possible code issues.

    Everytime your app is starting(means: everytime a new instance is starting or was recycled) you are trying to create table for context......can be problem with existence of tables that you are trying to recreate? Take a look at and read remarks carefully http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storageclient.cloudtableclient.createtablesfrommodel.aspx

    It's now recommended that you use the CreateTable or CreateTableIfNotExist method to create a table, rather than CreateTablesFromModel. It is not necessary to create a custom class that is derived from TableServiceContext in order to work with Table service data.

    Can be problem there????

    Try this code in webrole.cs:

     

           private void _createPolygonTable(CloudStorageAccount account)

            {

                CloudTableClient tableClient = account.CreateCloudTableClient(); // create table client

                if (!tableClient.CreateTableIfNotExist(PolygonDataContext.TableName)) // create table if not exists with bool value returned, TableName is const for this context ;-)

                { // if teble exists then delete entities in there

                    PolygonDataContext polygonCtxt = new PolygonDataContext(account.TableEndpoint.ToString(), account.Credentials);

                    polygonCtxt.EmptyTable(); 

                }                  

            }

    After all I still miss the point of deleting all content in context table.

     


    Looks like that was the culprit. I am past that problem now and will be back if I run into other issues. Thank you very much. 
    Dinesh Agarwal
    Wednesday, April 6, 2011 6:53 PM
  • Nice, I am glad I can help You :-) I will try to be in touch ;-)
    Thursday, April 7, 2011 7:00 AM
  • Rename the table name as Polygon or your property that returns IQueryable<PolygonEntity> as Polygons. Either one should work. I would also recommend what Peter said - do not use CreateTablesFromDataModel but use the explicit CreateTableIfNotExists.

    The other thing I noticed was you are calling SaveChanges for each entity. If the Partitionkey is the same for all entities being deleted, you could use Entity Group Transactions by using SaveChanges(SaveChangesOptions.Batch) with maximum of 100 entities at a time.

    Thanks,
    Jai

    Dear Jai,

    I understands that table name should be singular and I will do that. But is your concern something other than that?


    Dinesh Agarwal
    Thursday, April 7, 2011 6:13 PM
  • Sorry I was not clear in my previous response. The problem is CreateTablesFromDataModel looks for the property name and creates a table with that name. In this case it was Polygon. However, when accessing tables your table name constant is "Polygons" and hence you get a NotFound error since the table name created was different.

    Thanks,

    Jai

    Thursday, April 7, 2011 6:40 PM
  • Gotcha. Thank you.
    Dinesh Agarwal
    Friday, April 8, 2011 9:31 PM