Crash when using Double? property in SQLIte in Blazor Wasm (.Net6) - sqlite

I'm using Blazor Wasm with a SQLite clientdatabase. Like here (https://github.com/dotnetnoobie/BlazorAppSqlite)
public DbSet<Test> Tests { get; set; } = default!;
.....
public class Test
{
[Key]
public int Id { get; set; }
public double? NullableDoubleValue { get; set; }
}
......
var test = new Test();
test.Id = 1;
test.NullableDoubleValue = 1;
_appState.ClientSideDbContext.Tests.Add(test);
await _appState.ClientSideDbContext.SaveChangesAsync();
When the last line is executed, the Blazor app wil crash.
With this error in the log:
/__w/1/s/src/mono/mono/mini/aot-runtime-wasm.c:113
/__w/1/s/src/mono/mono/mini/aot-runtime-wasm.c:113
Uncaught ExitStatus
What change do I have to make to use a (nullable) double?

The issue seems to come from using float or double. The fix has been merged and it will probably be released with dotnet 7 as mentioned in this issue.
Description
Seeing a bug when using SQLitePCL.Raw preview and also see the same bug in Steve Sandersons Blaze Orbital sample when using double/float in entity classes. Works fine with decimals! Tried with EF Core and SQLite-net.
As a workaround, you can use decimal instead of float or double and it will work just fine.

Related

How to do Login with Firebase integration in .NET MAUI?

I'm trying to login with integration to social networks, more specifically to Google in .NET MAUI. I've done it with Xamarin Forms and it worked perfectly, however, in MAUI a standard error is occurring:
Error CS0246 The type or namespace name 'Android' could not be found (are you missing a using directive or an assembly reference?) LoginWithRedes (net6.0-ios), LoginWithRedes (net6.0-maccatalyst), LoginWithRedes (net6.0-windows10.0.19041) C:\MAUI\LoginWithRedes\LoginWithRedes\Platforms\Android\GoogleManager.cs
Libraries not being recognized
Packages I added to the project
Code of the GoogleManager.CS Class where the standard error occurs to me:
`[assembly: Dependency(typeof(GoogleManager))]
namespace LoginWithRedes.Platforms.Android
{
public class GoogleManager : Java.Lang.Object, IGoogleManager, GoogleApiClient.IConnectionCallbacks, GoogleApiClient.IOnConnectionFailedListener
{
public static GoogleApiClient _googleApiClient { get; set; }
public static GoogleManager Instance { get; private set; }
public bool IsLogedIn { get; set; }
Context _context;
public GoogleManager()
{
_context = global::Android.App.Application.Context;
Instance = this;
}
public void Login()
{
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
.RequestEmail()
.Build();
_googleApiClient = new GoogleApiClient.Builder((_context).ApplicationContext)
.AddConnectionCallbacks(this)
.AddOnConnectionFailedListener(this)
.AddApi(Auth.GOOGLE_SIGN_IN_API, gso)
.AddScope(new Scope(Scopes.Profile))
.Build();
Intent signInIntent = Auth.GoogleSignInApi.GetSignInIntent(_googleApiClient);
((MainActivity)Forms.Context).StartActivityForResult(signInIntent, 1);
_googleApiClient.Connect();
}
public void Logout()
{
var gsoBuilder = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn).RequestEmail();
GoogleSignIn.GetClient(_context, gsoBuilder.Build())?.SignOut();
_googleApiClient.Disconnect();
}
public void OnAuthCompleted(GoogleSignInResult result)
{
if (result.IsSuccess)
{
IsLogedIn = true;
Application.Current.MainPage = new MainPage();
}
else
{
}
}`
OnActivityResult method that I implemented in MainActivity class
If anyone can help me with this error, I would be very grateful.
Note: I'm new to Xamarin and Maui.
Thank you very much in advance
I'm also new to Maui, and in my experience, these errors were caused by using native Xamarin libraries in Maui. Xamarin targets each platform separately using separate nuget packages. Maui's combined 1-project architecture means you need to use packages that work for both at once.
At least when I was getting started a few months ago, these weren't readily available. Firebase client was not yet released for .NET 6.0 (Multiplatform by default).
Things may have changed since then. But I had great success using Firebase with this plugin https://github.com/TobiasBuchholz/Plugin.Firebase. It wraps up the platform specific libraries into a single project API, with a really easy to use c# interface. You can use await and stuff as you would expect. Calling the native APIs was difficult, and required a lot of code duplication. This plugin saves a lot of time, and I haven't yet run into any problems.
The documentation on the plugin is a bit sparse, but hey, it's free and works.

EF Core SQLite slow star-up performance on Xamarin

I faced with slow start-up experience of my Xamarin.Android application.
The first DbContext creation takes ~4.5 seconds (context has 24 tables). At first I thought that the reason for this is that EF Core needs time to scan the entity classes from DbContext and build the model (this makes sense for a large DbContext).
So, I created a test DbContext with only one table to check the relationship between the time to create a model on the number of tables in the model:
public class Log
{
[Key]
public int EntityId { get; set; }
public string Timestamp { get; set; }
public string Level { get; set; }
public string Exception { get; set; }
public string RenderedMessage { get; set; }
public string Properties { get; set; }
}
public class ApplicationLogDbContext : DbContext
{
public ApplicationLogDbContext(DbContextOptions<ApplicationLogDbContext> options)
: base(options) { }
public DbSet<Log> Logs { get; set; }
}
DbContext test code:
var options = new DbContextOptionsBuilder<ApplicationLogDbContext>()
.UseSqlite("Data Source=/storage/emulated/0/Android/data/***/files/ApplicationLog.db")
.Options;
var logContext = new ApplicationLogDbContext(options);
logContext.Database.EnsureCreated();
This code execution takes 3.3 seconds on my Samsung Galaxy S7. This test showed the inappropriateness of trying some solutions:
Use fewer entity classes (reduce connections between tables);
Split one application DbContext into several small context.
I also learn that:
EF Core doesn't have automatic migrations (I don't need to disable it);
I removed code first approach but it only partially helped to reduce the DbContext initialization time to 4 seconds;
If I delete the line with EnsureCreated, the execution time of the first request will increase by the same time;
There are many similar problems (here, GitHub), but they have no solution. Such issues have been reported even for EF6;
I didn't notice any significant changes after installing Microsoft.EntityFrameworkCore.Sqlite 5.0.0-preview.6.20312.4 (application has the same execution time: ~3.3 seconds);
PRAGMA journal_mode=WAL; increased initialization speed (EF Core 2.2). This is not stable, but sometimes the initialization time is reduced by 300-400 ms.
If application has 2 DbContext for different databases (1st with one entity, 2nd with 25 entities) EF Core initialization time for the second context is drastically reduced to ~1 second. First context initialization is still slow;
Initialization completes faster (~30%) without an attached debugging session.
Example with EF Core 5 Preview 6 GitHub
What approach can I use to somehow hide this initialization time from the user, but get data for the main activity?
Is there any configuration tips that can help to increase default configuration initialization time?
Will performance improve when running .NET 5?

Deployed SQLite database is empty after deployment of Universal App

I use in SQLite database in UWP. It has a few tables and is located in Assets folder and has build action marked as "Content".
Under development machine it works fine.
But after deployment to MS Windows 10 tablet it has the error
SQLite error 1 no such table Companies
It corresponds to the code
using (MobileContext db = new MobileContext())
{
companiesList.ItemsSource = db.Companies.ToList();
...
}
var createdResult = Database.EnsureCreated(); // It gives false so
I assume based on https://learn.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.infrastructure.databasefacade.ensurecreated?view=efcore-2.1 that database exists.
I have tried
optionsBuilder.UseSqlite("Data Source=" + ApplicationData.Current.LocalFolder.Path + #"\Mobile.db");
optionsBuilder.UseSqlite("Data Source=Mobile.db");
Any clue folk? Thanks!
P.S. I use Microsoft.EntityFrameworkCore to accees SQLite.
P.S. #2 I have tried this solution https://social.msdn.microsoft.com/Forums/en-US/1a933b13-09ee-46ec-9045-e2f567b6048c/uwp-sqlite-error-1-no-such-table-name-table?forum=wpdevelop but it does not work.
Derive from official document,
Connection strings in a UWP application are typically a SQLite connection that just specifies a local filename. They typically do not contain sensitive information, and do not need to be changed as an application is deployed. As such, these connection strings are usually fine to be left in code, as shown below. If you wish to move them out of code then UWP supports the concept of settings
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=blogging.db");
}
}
And the default path of db file is application LocalFolder. It looks like this C:\Users\vxx\AppData\Local\Packages\e045f456-27d9-4966-b639-01e2281b249f_7jxxxxxxxxxx\LocalState. If your configuration is same as above, when deploy in new machine, the content of db file is empty.
OP Update
I just commented some decorations of the class like [Table("Companies")] and [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] and it works now!

Can we have DataContractSerializer, XMLFormatSerializer both in same service(ServiceContract) for different methods(OperationContract)?

Code:
public interface IServices
{
[OperationContract]
[XmlSerializerFormat]
GetProductsResponse Getproducts(GetProductsRequest productsrequest);
[OperationContract]
SaveProductsResponse SaveProducts1(SaveProductsRequest1 productsrequest);
}
[DataContract]
public class SaveProductsRequest1
{
[DataMember]
public List<Person> Persons;
}
[DataContract]
public class Person
{
[DataMember]
public int Id;
}
Client :
ServicesClient client = new ServicesClient();
SaveProductsRequest1 req = new SaveProductsRequest1();
req.Persons = new List<Person> { new Person { Id = 10 } }.ToArray();
client.SaveProducts1(req);
I am invoking the SaveProducts1 call from client side and not able to get the value '10' in my service side(seems deserialization issue). But when I remove [XmlSerializerFormat] attribute from Getproducts call, it just works fine and I am able to see the value 10.
Why is it happening(Why SaveProducts1 depends on Getproducts OperationContract)? What workaround I should provide, when I want to use both xml and datacontract serialization? Any help appreciated.
Note: I have very updated proxy. I am not seeing any issue in proxy. Even I tried with one sample and getting the same issue
Did you refresh your client service reference after adding the XmlSerializerFormat attribute? It could be that the contracts don't match any longer.

Generate a form from a poco object

Say you had a config object
public class MyConfig{
public int PageSize{get;set;}
public string Title{get;set;}
}
and you want to automatically generate a asp.net form to edit the properties on this object.
Do you know of any frameworks to do this automagically?
I know of MS Dynamic data, but seems I need to have the whole stack (database, linq, objects) to get this up and running. So I was thinking of something simpler..
Sorry for jumping in late. There are several ways to use Dynamic Data with POCO.
Use the DynamicObjectDataSource which is found in Futures and Preview releases of Dynamic Data, starting with July 2008 Futures. When looking in a Preview release, it contains a Futures assembly, Microsoft.Web.DynamicData.dll.
When using ASP.NET 4.0 (now in Beta), you can call a new extension method, EnableDynamicData(). See the "SimpleDynamicDataSamples" project that comes with DD Preview 4 and later.
Here's an example from that code that uses an ObjectDataSource and the POCO class called "Product".
[MetadataType(typeof(Product.Metadata))]
public partial class Product {
public class Metadata {
[Required]
public string ProductName { get; set; }
[Range(0, 100)]
public decimal UnitPrice { get; set; }
}
}
public partial class ObjectDataSourceSample : System.Web.UI.Page {
protected void Page_Init() {
// Extension method syntax
ProductsList.EnableDynamicData(typeof(Product));
// Explicit syntax
// MetaTable table = MetaTable.CreateTable(typeof(Product));
// MetaTable.MapControl(ProductsList, table);
// ProductsList.ColumnsGenerator = new DefaultAutoFieldGenerator(table);
}
}
I was under the impression that you could modify the T4 templates used by dynamic data (Not sure if you can remove the data access part).
Have you looked at just using T4 on its own.

Resources