Linq update Trouble - linq

I want to update my Azure database using linq in my xamarin.forms project
below is the initalise and sync methods that connect to the database. These work successfully. My problem is that I want to update a record is the database. Any suggestions are welcome.
MobileServiceClient client = null;
IMobileServiceSyncTable<Shop> ShopTable2;
bool isInitialised;
public async Task Initialize()
{
if (isInitialised)
{
return;
}
this.client = new MobileServiceClient("link to database");
MobileServiceClient client = new MobileServiceClient("link to databse");
const string path = "user.db";
var store = new MobileServiceSQLiteStore(path);
store.DefineTable<Shop>();
await this.client.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler());
ShopTable2= this.client.GetSyncTable<Shop>();
isInitialised = true;
}
sync method
public async Task Sync()
{
try
{
await shopTable2.PullAsync("allusers3", shopTable2.CreateQuery());
await client.SyncContext.PushAsync();
}
catch (Exception ex)
{
Debug.WriteLine("Unable to sync " + ex);
}
}
where I want to update the records here:
public async void BuyProducts(string Pname)
{
string productname = Pname;
await Initialize();
await SyncBookings();
List<Shop_TBL> item = await BookingsTable2
.Where(todoItem => todoItem.ProductName == productname)
.ToListAsync();
}

Assuming you are using Entity Framework as your ORM:
Select the entity you want to update.
var book = db.Books.First(b => b.Id == _id);
Change the property:
book.Name = "Something else";
Save the changes:
await db.SaveChangesAsync();
or
db.SaveChanges();
That's how you do an update.

Related

Trying to create the database using ABP framework while DB Migration

I have inserted connectionstring in "[AbpTenantConnectionStrings]" table for same tenant id.
My objective is to create both the DB and migrage the DB
DB
while running below code only "Default Db is creating", can anyone let me know how to create and migrate other DB as well. what changes need to be done in the below code.
var tenants = await _tenantRepository.GetListAsync(includeDetails: true);
var migratedDatabaseSchemas = new HashSet<string>();
foreach (var tenant in tenants)
{
using (_currentTenant.Change(tenant.Id))
{
if (tenant.ConnectionStrings.Any())
{
var tenantConnectionStrings = tenant.ConnectionStrings
.Select(x => x.Value)
.ToList();
if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings))
{
await MigrateDatabaseSchemaAsync(tenant);
migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings);
}
}
await SeedDataAsync(tenant);
}
After the below changes able to migrate or create the Db based on the connection-string inserted in "AbpTenantConnectionStrings":
public async Task MigrateAsync()
{
var initialMigrationAdded = AddInitialMigrationIfNotExist();
//var str = (await _connectionResolver.ResolveAsync("Default1"));
if (initialMigrationAdded)
{
return;
}
Logger.LogInformation("Started database migrations...");
await MigrateDatabaseSchemaAsync();
await SeedDataAsync();
Logger.LogInformation($"Successfully completed host database migrations.");
var tenants = await _tenantRepository.GetListAsync(includeDetails: true);
var migratedDatabaseSchemas = new HashSet<string>();
foreach (var tenant in tenants)
{
using (_currentTenant.Change(tenant.Id))
{
if (tenant.ConnectionStrings.Any())
{
var tenantConnectionStrings = tenant.ConnectionStrings
.Select(x => x.Value)
.ToList();
tenantConnectionStrings.ForEach(async s =>
{
await MigrateDatabaseSchemaAsync(s);
// migratedDatabaseSchemas.AddIfNotContains(s);
});
//if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings))
//{
// await MigrateDatabaseSchemaAsync(tenant);
// migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings);
//}
}
await SeedDataAsync(tenant);
}
Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations.");
}
Logger.LogInformation("Successfully completed all database migrations.");
Logger.LogInformation("You can safely end this process...");
}
private async Task MigrateDatabaseSchemaAsync(string str)
{
//Logger.LogInformation(
// $"Migrating schema for {(tenant == null ? "host" : tenant.Name + " tenant")} database...");
foreach (var migrator in _dbSchemaMigrators)
{
await migrator.MigrateAsync(str);
}
}
public interface IBookStoreDbSchemaMigrator
{
Task MigrateAsync();
Task MigrateAsync(string con);
}
public class EntityFrameworkCoreBookStoreDbSchemaMigrator
: IBookStoreDbSchemaMigrator, ITransientDependency
{
private readonly IServiceProvider _serviceProvider;
public EntityFrameworkCoreBookStoreDbSchemaMigrator(
IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task MigrateAsync()
{
/* We intentionally resolving the BookStoreMigrationsDbContext
* from IServiceProvider (instead of directly injecting it)
* to properly get the connection string of the current tenant in the
* current scope.
*/
await _serviceProvider.GetRequiredService<BookStoreMigrationsDbContext>()
.Database
.MigrateAsync();
}
public async Task MigrateAsync(string con)
{
var context = _serviceProvider
.GetRequiredService<BookStoreMigrationsDbContext>();
context.Database.SetConnectionString(con);
context.Database.Migrate();
}
}
Let me know if anyone has suggestions or a better approach.

Puppeteer LaunchAsync throwing exception

I have an existing ASPNET Web Application. The front end is HTML/JavaScript and the backend is WebAPI 2. We have been using NRECO.PDFGenerator to drop PDFs to the users, this uses a the QT browser and debugging is becoming a chore. I found PuppeteerSharp and figured I'd give it a try.
I installed the libs using nuget, added an Async method to one of my Web Api Controllers but when I call it the LaunchAsync method just crashed.
[Route("api/pdf/v2/download")]
public IHttpActionResult V2Download([FromBody] Models.PDF.List _pdf) {
Models.Message.Response _return = new Models.Message.Response();
_return.Message = "Success!";
_return.Now = DateTime.Now;
try
{
string[] argu = null;
Meh(argu);
}
catch (Exception ex)
{
_return.Message = ex.Message;
_return.Severity = 3;
}
return Ok(_return);
}
public static async Task Meh(string[] args)
{
var options = new LaunchOptions
{
Headless = true,
Args = new[] {"--no-sandbox" }
};
Debug.WriteLine("Downloading chromium");
await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
Debug.WriteLine("Navigating google");
using (var browser = await Puppeteer.LaunchAsync(options))
using (var page = await browser.NewPageAsync())
{
Debug.WriteLine("Navigating to page");
await page.GoToAsync("http://www.google.com");
Debug.WriteLine("Generating PDF");
await page.PdfAsync(Path.Combine(Directory.GetCurrentDirectory(), "google.pdf"));
Debug.WriteLine("Export completed");
if (!args.Any(arg => arg == "auto-exit"))
{
Console.ReadLine();
}
}
}
I'm not sure where to go from here. This is the console output. There's more...
Navigating google
The thread 0x3418 has exited with code 0 (0x0).
Exception thrown: 'System.NullReferenceException' in System.Web.dll
Exception thrown: 'System.NullReferenceException' in mscorlib.dll
The project is using framework 4.7.2
Solution
Everything that touches the Async method needs to also be Async. Also, Passing null args will cause problems as well.
Here's a code sample.
//[Authorize]
[Route("api/pdf/v2/download")]
public async Task<IHttpActionResult> V2Download([FromBody] Models.PDF.List _pdf) {
Models.Message.Response _return = new Models.Message.Response();
_return.Message = "Success!";
_return.Now = DateTime.Now;
try
{
string[] argu = { };
await Meh(argu);
}
catch (Exception ex)
{
_return.Message = ex.Message;
_return.Severity = 3;
}
return Ok(_return);
}
public static async Task Meh(string[] args)
{
var options = new LaunchOptions
{
Headless = true
};
Debug.WriteLine("Downloading chromium");
await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
Debug.WriteLine("Navigating google");
using (var browser = await Puppeteer.LaunchAsync(options))
using (var page = await browser.NewPageAsync())
{
Debug.WriteLine("Navigating to page");
await page.GoToAsync("http://www.google.com");
Debug.WriteLine("Generating PDF");
await page.PdfAsync(Path.Combine(Directory.GetCurrentDirectory(), "google.pdf"));
Debug.WriteLine(Path.Combine(Directory.GetCurrentDirectory(), "google.pdf"));
Debug.WriteLine("Export completed");
if (!args.Any(arg => arg == "auto-exit"))
{
Console.ReadLine();
}
}
}

Exception of type 'System.Collections.Generic.KeyNotFoundException' was thrown ? in Xamarin.Forms

i wanna use simple database in Xamarin Forms. So i used this code;
public partial class DBExample : ContentPage
{
string _dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal),"myDB.db3");
public DBExample ()
{
InitializeComponent ();
}
private async void InsertButton(object sender, EventArgs e)
{
SQLiteConnection db=null;
try
{
db = new SQLiteConnection(_dbPath);
}
catch (Exception ex)
{
await DisplayAlert(null, ex.Message, "OK");
}
db.CreateTable<Users>();
var maxPk = db.Table<Users>().OrderByDescending(c => c.Id).FirstOrDefault();
Users users = new Users()
{
Id = (maxPk == null ? 1 : maxPk.Id + 1),
Name = userName.Text
};
db.Insert(users);
await DisplayAlert(null,userName.Text + "saved","OK");
await Navigation.PopAsync();
}
}
and i have problem. You can see it in Headtitle.
"Exception of type 'System.Collections.Generic.KeyNotFoundException' was thrown"
im waiting your support. Thanks for feedback.

TaskContinuation.cs not found exception while accessing WebAPI Task

I'm trying to fetch records from a db cursor from the Client app.
Debugging Web API shows that the Cursor returns records but when returning to the Client it throws mscorlib.pdb not loaded window and clicking on Load option it throws TaskContinuation.cs not found exception
Code snippets as below ( removed irrelevant codes for readability )
WebAPI
[HttpPost("{values}")]
public async Task<ActionResult> Post([FromBody] JToken values)
{
// code removed for readility
string[] cursors = { };
cursors = await cursor.GetRpts();
CursorClass firstCursor = JsonConvert.DeserializeObject<CursorClass>(cursors[0]);
return new OkObjectResult(cursors);
}
public async Task<string[]> GetRpts()
{
try
{
DataTable[] dataTables;
CursorClass[] cursorClasses = new CursorClass[5];
//stripped some code
using (DataAccess dataAccess = new DataAccess()
{
ParamData = PrepareDoc(),
ProcedureName = Constants.Rpt,
RecordSets = this.CursorNumbers,
})
{
Int32 errorNumber = await dataAccess.RunComAsync();
dataTables = dataAccess.TableData;
};
//fetching code stripped off
string[] _cursors = Array.ConvertAll(cursorClasses, JsonConvert.SerializeObject);
return _cursors;
}
catch (Exception ex)
{
string tt = ex.Message;
}
}
public async Task<Int32> RunComAsync()
{
Int32 returnValue = 0;
try
{
//open db connection
//---------- Running the Command in asysnc mode ----------
Task<int> task = new Task<int>(oracleCommand.ExecuteNonQuery);
task.Start();
returnValue = await task;
//--------------------------------------------------------
OracleRefCursor[] refCursor = { null, null, null, null, null };
for (int _sub = 0; _sub < RecordSets; _sub++)
{
//DT declaration / connection code removed
dataAdapter.Fill(dataTable, refCursor[_sub]);
TableData[_sub] = dataTable;
}
}
catch (Exception ex)
{
return LogMsg(ex);
}
finally
{
this.Dispose(true);
}
CloseConnection();
return LogMsg(null,"Successful Operation");
}
Client
private async Task<HttpStatusCode> CallService()
{
HttpResponseMessage _response = null;
try
{
using (HttpRequestMessage requestMessage = new HttpRequestMessage()
{
Content = new System.Net.Http.StringContent(JsonRepo, System.Text.Encoding.UTF8, HeaderJson),
RequestUri = new Uri(UriString),
Method = HttpMethod.Post,
})
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", Utils.TOKEN) ;
_response = await httpClient.SendAsync(requestMessage);
if (_response.IsSuccessStatusCode)
{
string httpResponse = await _response.Content.ReadAsStringAsync();
httpString = JsonConvert.DeserializeObject<string[]>(httpResponse);
}
}
}
return ErrorCode;
}
Is that something related to async operation? while debugging the API it confirms the Datatable with records . Any inputs are deeply appreciated.
error image
TIA

Azure Notification Hub and WP8 Intermitant notifications

This is a fairly long piece of code but I am getting nowhere with this and cannot see any issues, although I am new to using notification hubs. I am trying to register for targeted notifications (the logged on user) using the notification hub in Azure. After the registration, a test notification is sent.
The issue I am having is that sometimes the notification is sent to the device, and sometimes it is not. It mostly isn't but occasionally when I step through the code on the server, i will get the notification on the emulator come through. Once when I deployed the app to my phone the notification came though on the emulator! I cannot discover a pattern.
My Controller class looks like this;
private NotificationHelper hub;
public RegisterController()
{
hub = NotificationHelper.Instance;
}
public async Task<RegistrationDescription> Post([FromBody]JObject registrationCall)
{
var obj = await hub.Post(registrationCall);
return obj;
}
And the helper class (which is used elsewhere so is not directly in the controller) looks like this;
public static NotificationHelper Instance = new NotificationHelper();
public NotificationHubClient Hub { get; set; }
// Create the client in the constructor.
public NotificationHelper()
{
var cn = "<my-cn>";
Hub = NotificationHubClient.CreateClientFromConnectionString(cn, "<my-hub>");
}
public async Task<RegistrationDescription> Post([FromBody] JObject registrationCall)
{
// Get the registration info that we need from the request.
var platform = registrationCall["platform"].ToString();
var installationId = registrationCall["instId"].ToString();
var channelUri = registrationCall["channelUri"] != null
? registrationCall["channelUri"].ToString()
: null;
var deviceToken = registrationCall["deviceToken"] != null
? registrationCall["deviceToken"].ToString()
: null;
var userName = HttpContext.Current.User.Identity.Name;
// Get registrations for the current installation ID.
var regsForInstId = await Hub.GetRegistrationsByTagAsync(installationId, 100);
var updated = false;
var firstRegistration = true;
RegistrationDescription registration = null;
// Check for existing registrations.
foreach (var registrationDescription in regsForInstId)
{
if (firstRegistration)
{
// Update the tags.
registrationDescription.Tags = new HashSet<string>() {installationId, userName};
// We need to handle each platform separately.
switch (platform)
{
case "windows":
var winReg = registrationDescription as MpnsRegistrationDescription;
winReg.ChannelUri = new Uri(channelUri);
registration = await Hub.UpdateRegistrationAsync(winReg);
break;
case "ios":
var iosReg = registrationDescription as AppleRegistrationDescription;
iosReg.DeviceToken = deviceToken;
registration = await Hub.UpdateRegistrationAsync(iosReg);
break;
}
updated = true;
firstRegistration = false;
}
else
{
// We shouldn't have any extra registrations; delete if we do.
await Hub.DeleteRegistrationAsync(registrationDescription);
}
}
// Create a new registration.
if (!updated)
{
switch (platform)
{
case "windows":
registration = await Hub.CreateMpnsNativeRegistrationAsync(channelUri,
new string[] {installationId, userName});
break;
case "ios":
registration = await Hub.CreateAppleNativeRegistrationAsync(deviceToken,
new string[] {installationId, userName});
break;
}
}
// Send out a test notification.
await SendNotification(string.Format("Test notification for {0}", userName), userName);
return registration;
And finally, my SendNotification method is here;
internal async Task SendNotification(string notificationText, string tag)
{
try
{
var toast = PrepareToastPayload("<my-hub>", notificationText);
// Send a notification to the logged-in user on both platforms.
await NotificationHelper.Instance.Hub.SendMpnsNativeNotificationAsync(toast, tag);
//await hubClient.SendAppleNativeNotificationAsync(alert, tag);
}
catch (ArgumentException ex)
{
// This is expected when an APNS registration doesn't exist.
Console.WriteLine(ex.Message);
}
}
I suspect the issue is in my phone client code, which is here and SubscribeToService is called immediately after WebAPI login;
public void SubscribeToService()
{
_channel = HttpNotificationChannel.Find("mychannel");
if (_channel == null)
{
_channel = new HttpNotificationChannel("mychannel");
_channel.Open();
_channel.BindToShellToast();
}
_channel.ChannelUriUpdated += async (o, args) =>
{
var hub = new NotificationHub("<my-hub>", "<my-cn>");
await hub.RegisterNativeAsync(args.ChannelUri.ToString());
await RegisterForMessageNotificationsAsync();
};
}
public async Task RegisterForMessageNotificationsAsync()
{
using (var client = GetNewHttpClient(true))
{
// Get the info that we need to request registration.
var installationId = LocalStorageManager.GetInstallationId(); // a new Guid
var registration = new Dictionary<string, string>()
{
{"platform", "windows"},
{"instId", installationId},
{"channelUri", _channel.ChannelUri.ToString()}
};
var request = new HttpRequestMessage(HttpMethod.Post, new Uri(ApiUrl + "api/Register/RegisterForNotifications"));
request.Content = new StringContent(JsonConvert.SerializeObject(registration), Encoding.UTF8, "application/json");
string message;
try
{
HttpResponseMessage response = await client.SendAsync(request);
message = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
message = ex.Message;
}
_registrationId = message;
}
}
Any help would be greatly appriciated as I have been stuck on this now for days! I know this is a lot of code to paste up here but it is all relevant.
Thanks,
EDIT: The SubscribeToService() method is called when the user logs in and authenticates with the WebAPI. The method is here;
public async Task<User> SendSubmitLogonAsync(LogonObject lo)
{
_logonObject = lo;
using (var client = GetNewHttpClient(false))
{
var logonString = String.Format("grant_type=password&username={0}&password={1}", lo.username, lo.password);
var sc = new StringContent(logonString, Encoding.UTF8);
var response = await client.PostAsync("Token", sc);
if (response.IsSuccessStatusCode)
{
_logonResponse = await response.Content.ReadAsAsync<TokenResponseModel>();
var userInfo = await GetUserInfoAsync();
if (_channel == null)
SubscribeToService();
else
await RegisterForMessageNotificationsAsync();
return userInfo;
}
// ...
}
}
I have solved the issue. There are tons of fairly poorly organised howto's for azure notification hubs and only one of them has this note toward the bottom;
NOTE:
You will not receive the notification when you are still in the app.
To receive a toast notification while the app is active, you must
handle the ShellToastNotificationReceived event.
This is why I was experiencing intermittent results, as i assumed you would still get a notification if you were in the app. And this little note is pretty well hidden.
Have you used proper tag / tag expressions while register/send the message. Also, Where are you storing the id back from the notification hub. It should be used when you update the channel uri (it will expire).
I would suggest to start from scratch.
Ref: http://msdn.microsoft.com/en-us/library/dn530749.aspx

Resources