问题
I am trying to get using the Azure Backend with Sync to work for my app. It looks like PullAsync is not populating my local table though.
My Table is set up like this:
private IMobileServiceSyncTable<Familie> FamilienTable = App.MobileService.GetSyncTable<Familie>(); // offline sync
Some code first. Initializing the table like this:
if (!App.MobileService.SyncContext.IsInitialized)
{
var store = new MobileServiceSQLiteStore("localGarden.db");
store.DefineTable<Familie>();
await App.MobileService.SyncContext.InitializeAsync(store);
}
I can see that the table is created and it is on my local system later (already tried setting up a new table, too).
And a little later in my code this is called:
try
{
await FamilienTable.PullAsync(null, FamilienTable.CreateQuery());
}
catch (Exception ex)
{
errorString = "Pull failed: " + ex.Message +
"\n\nIf you are still in an offline scenario, " +
"you can try your Pull again when connected with your Mobile Serice.";
}
if (errorString != null)
{
MessageDialog d = new MessageDialog(errorString);
await d.ShowAsync();
}
I set this up originally based on https://azure.microsoft.com/en-us/documentation/articles/mobile-services-xamarin-ios-get-started-offline-data/ and adapted to using a Win10 App. This is using Microsoft.Azure.Mobile.Client.SQLitestore 2.0.1 mainly.
I know that I need to replace the null in the PullAsync with a string for incremental updates in the future.
Using fiddler I discovered that there are 2 calls to my node.js powered API on Azure during the pullAsync: [removed].azurewebsites.net/tables/Familie?$skip=0&$top=50&__includeDeleted=true (which returns a JSON with 6 rows I have in my table) and immidiatly after that [removed].azurewebsites.net/tables/Familie?$skip=6&$top=50&__includeDeleted=true which returns an empty JSON.
My local table stays empty though.
Can someone tell me, if that behavior is by design, explain why I get 2 calls and give me an idea where to look for the reason why my local table is not populated?
Thank you very much!
Additional Info: Output of LoggingHandler:
CREATE TABLE IF NOT EXISTS [Familie] ([id] INTEGER PRIMARY KEY, [Name] TEXT, [Deleted] BOOLEAN, [Version] DATETIME, [createdAt] DATETIME, [updatedAt] DATETIME)
CREATE TABLE IF NOT EXISTS [__operations] ([id] TEXT PRIMARY KEY, [kind] INTEGER, [state] INTEGER, [tableName] TEXT, [tableKind] INTEGER, [itemId] TEXT, [item] TEXT, [createdAt] DATETIME, [sequence] INTEGER, [version] INTEGER)
CREATE TABLE IF NOT EXISTS [__errors] ([id] TEXT PRIMARY KEY, [httpStatus] INTEGER, [operationVersion] INTEGER, [operationKind] INTEGER, [tableName] TEXT, [tableKind] INTEGER, [item] TEXT, [rawResult] TEXT)
CREATE TABLE IF NOT EXISTS [__config] ([id] TEXT PRIMARY KEY, [value] TEXT)
BEGIN TRANSACTION
INSERT OR IGNORE INTO [__config] ([id]) VALUES (@p0)
The thread 0x2fcc has exited with code 0 (0x0).
UPDATE [__config] SET [value] = @p0 WHERE [id] = @p1
COMMIT TRANSACTION
SELECT * FROM [__operations] ORDER BY [sequence] DESC LIMIT 1
SELECT COUNT(1) AS [count] FROM [__operations]
Pulling changes from remote server
'Gemüsebeetplaner.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Users\Jens\documents\visual studio 14\Projects\Gemüsebeetplaner\Gemüsebeetplaner\bin\x86\Debug\AppX\System.Linq.Queryable.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
SELECT * FROM [__operations] WHERE ([tableName] = @p1) LIMIT 0
SELECT COUNT(1) AS [count] FROM [__operations] WHERE ([tableName] = @p1)
Pulling changes from remote server
SELECT * FROM [__operations] WHERE ([tableName] = @p1) LIMIT 0
SELECT COUNT(1) AS [count] FROM [__operations] WHERE ([tableName] = @p1)
SELECT * FROM [Familie] ORDER BY [Name]
Additonal Info 2:
**Screenshots of the tables ** Screenshot
This is the log with parameters enabled: Pulling changes from remote server
SELECT * FROM [__operations] WHERE ([tableName] = @p1) LIMIT 0
@p1:Familie
SELECT COUNT(1) AS [count] FROM [__operations] WHERE ([tableName] = @p1)
@p1:Familie
{
"count": 0
}
Pulling changes from remote server
SELECT * FROM [__operations] WHERE ([tableName] = @p1) LIMIT 0
@p1:Familie
SELECT COUNT(1) AS [count] FROM [__operations] WHERE ([tableName] = @p1)
@p1:Familie
{
"count": 0
}
SELECT * FROM [Familie] ORDER BY [Name]
The thread 0x24c8 has exited with code 0 (0x0).
The thread 0x1474 has exited with code 0 (0x0).
The thread 0x1a40 has exited with code 0 (0x0).
Class
public class Familie
{
[JsonProperty(PropertyName = "Id")]
public int Id { get; set; }
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
}
回答1:
There will always be at least 2 calls when doing a Pull operation, because the client has no way of knowing the server batch size. In your example, the server sent 6 records, so the client needs to do another query to find out if there are more records
What is the symptom of your local table not being populated? Do you get empty results when you do a query of FamilienTable
?
Does the first call return results? If so, there must be something strange in how the local database is being populated. Try adding logging SQLite store to your app, which will log all local database statements, here's a sample: https://github.com/Azure-Samples/app-service-mobile-dotnet-todo-list-files/blob/master/src/client/MobileAppsFilesSample/Helpers/LoggingHandler.cs
来源:https://stackoverflow.com/questions/35238416/using-mobileservice-getsynctable-pullasync-trouble