EntityFrameworkCore with SQLite on Xamarin returns System.NotImplemented - xamarin

I created Xamarin.Forms Windows UWP and Android application with shared project.
To both(UWP and Android) I imported latest stable NuGet packages:
Microsoft.EntityFramework version 1.0.0, Microsoft.EntityFramework.Sqlite version 1.0.0 and Xamarin.Forms 2.3.1.114.
On shared project I created very simple data model:
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string Notes { get; set; }
}
and very simple data context:
public class DataDbContext: DbContext
{
public static string DatabasePathName;
public DataDbContext()
: base()
{
}
public DataDbContext(DbContextOptions options)
: base(options)
{
}
public DbSet<User> Users { get; set; }
protected override void OnConfiguring(
DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite(
String.Format("Filename={0}", DataDbContext.DatabasePathName));
base.OnConfiguring(optionsBuilder);
}
}
(The model uses, according to docs.efproject.net, an implicit definition of the field Id as the key and autoincrement.)
Now I initialize database: First set the platform dependent property DatabasePathName and second I'll add three User items to each. I assume that the values of these records will later be read from Resources. At this point, it is just I enter as literals. Records are saved by SaveChanges() method(both UWP and Android returns 3 (saved records)).
Now, if I run Windows UWP application and retrive these records by:
List<User> users = dbContext.Users.ToList();
and everything is as it should be. I read the records, so do I get a value which I put in a TextBlock control.
But if I use the same code in Xamarin Android Application, this code throws System.NotImplementedException exception.
I don't know why. Thank you for the advice.

There are still a few known issues with Xamarin's implementation of the .NET Standard. See aspnet/Microsoft.Data.Sqlite#255 for more details. We'll keep that issue up-to-date as Xamarin lights up.

Related

Can't cast database type character to Guid

I updated my solution from .Net 3.1 to .Net 6. Also updated the Npgsql nuget package from 5.0.10 to 6.0.4 as part of this upgrade.
Since then, I am receiving an error "Can't cast database type character to Guid" when I try to retreive data from the database.
My mapping in the context file is
entity.Property(e => e.UserId).HasColumnName("user_id").HasColumnType("CHAR(36)");
In C# class, this property is a GUID.
Is there some mapping update with the newer version of npgsql?
EF Core has a built-in value converter which implicitly converts .NET Guid properties to text columns (see docs. Note that PostgreSQL has a full UUID type - that's a better way to store GUIDs in the database, rather than as text.
This works in EF Core 6.0.4 - if you're encountering trouble, please produce a minimal, runnable code sample and add it to your question above.
Working 6.0 code:
await using var ctx = new BlogContext();
await ctx.Database.EnsureDeletedAsync();
await ctx.Database.EnsureCreatedAsync();
ctx.Blogs.Add(new Blog { Guid = Guid.NewGuid()});
await ctx.SaveChangesAsync();
_ = await ctx.Blogs.ToListAsync();
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseNpgsql(#"Host=localhost;Username=test;Password=test")
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
}
public class Blog
{
public int Id { get; set; }
public string Name { get; set; }
[Column(TypeName = "CHAR(36)")]
public Guid Guid { get; set; }
}

Why am I getting "Type does not exist" error adding a new razor page using entity framework

I am experimenting with Visual Studio 2022 and EF Core 6. I created a solution with three projects, one with my razor pages one with my dbcontext and one with my entity. I was able to get the migration working with no issue, creating the database and single table which to me indicates I have everything working properly, but when I go to add a razor page and allow VS to wire up a "List" template for me, it spins for a minute and gives me an error: A type with the name Scaffolding.Entities.EncylopediaEntry does not exist.
Here is the class that apparently doesn't exist
using System.ComponentModel.DataAnnotations;
namespace Scaffolding.Entitites
{
public class EncylopediaEntry
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
}
And here is the DbContext with a hard coded connection string for now as I'm trying to figure out why scaffolding isn't working
using Microsoft.EntityFrameworkCore;
using Scaffolding.Entitites;
namespace ScaffoldingTest.Data
{
public class ScaffoldingContext : DbContext
{
public DbSet<EncylopediaEntry> encyclopediaEntries { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("{remove}");
}
}
}
I'd got same error. Visual Studio 2022 (preview too) with NET 6.0.
I installed NET 5.0 and tested with new project net 5 then works well.
But not with NET 6.0.

Serialization attributes on TableEntity in Azure Table Storage

Im using web API to return data in azure table storage. Im returning a class that I 'm inheriting TableEntity in a class and adding properties but want to keep to the .Net convention of capitalized property names but also keep to the JavaScript/json convention of lowercase properties names.
I've tried adding the Json.net property attributes to the class but it appears to be ignored. E.g.:
[JsonProperty("id")]
public string ID {get;set;}
If the instance has a value set on ID, null is represent in the serialized result.
According to your description, I tested this issue on my side and found it works well on my side and Azure. Here is my detailed steps, you could refer to it.
Create a controller named UserInfoController in the Web API application with the Get function like this:
// GET: api/UserInfo
[HttpGet]
public async Task<string> Get()
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(<your-Storage-ConnectionString>);
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable cloudTable = tableClient.GetTableReference("UserInfo");
TableQuery<User> query = new TableQuery<User>()
.Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "Grade Four"));
var results =await cloudTable.ExecuteQuerySegmentedAsync(query, null);
//Serialize the object to string by using the latest stable version of Newtonsoft.Json
string jsonString = JsonConvert.SerializeObject(results);
return jsonString;
}
Entity
public class User : TableEntity
{
public User(string partitionKey, string rowKey)
{
this.PartitionKey = partitionKey;
this.RowKey = rowKey;
}
public User() { }
[JsonProperty("id")]
public long ID { get; set; }
[JsonProperty("username")]
public string UserName { get; set; }
[JsonProperty("phone")]
public string Phone { get; set; }
[JsonProperty("age")]
public int Age { get; set; }
}
Result
Deploy the Web API application to Azure, then you could find the following result by calling the function via Fiddler.
In summary, please try to check the version of Json.NET you are using. If you aren't using the latest (9.0.1), then please try to upgrade to the latest version and run your application again to find whether it could work as expected.
FYI - while this doesn't answer the direct answer of how to get TableEntity to respect JSON.net attributes... I was able to solve the use case by overriding the ReadEntity and WriteEntity method in the inherited class:
e.g.
public class User : TableEntity{
//Upper case name
public string Name {get; set};
public override void ReadEntity(IDictionary<string, AzureTableStorage.EntityProperty> properties, OperationContext operationContext){
base.ReadEntity(properties, operationContext);
//lower case
this.Name = properties["name"];
}

Using Automapper to map object to realm object with Xamarin and c#

I am creating an Xamarin.iOS app and a Realm database.I would like to keep my POCO objects separate from my RealmObject so what I did was use a repository pattern and within the repository I tried to use AutoMapper to map the POCO to the RealmObject
e.g. (subset)
public class PlaceRepository : IPlaceRepository
{
private Realm _realm;
public PlaceRepository(RealmConfiguration config)
{
_realm = Realm.GetInstance(config);
}
public void Add(Place place)
{
using (var trans = _realm.BeginWrite())
{
var placeRealm = _realm.CreateObject<PlaceRealm>();
placeRealm = Mapper.Map<Place, PlaceRealm>(place);
trans.Commit();
}
}
So, if I debug my code everything maps OK and placeRealm is populated OK but when I commit nothing gets saved to the Realm db. The following is my RealmObject
public class PlaceRealm : RealmObject
{
[ObjectId]
public string Guid { get; set; }
public string Title { get; set; }
public string Notes { get; set; }
}
and this is my POCO Place
public class Place
{
public string Guid { get; set; }
public string Title { get; set; }
public string Notes { get; set; }
}
And AutoMapper is initialized like so:
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Place, PlaceRealm>();
cfg.CreateMap<PlaceRealm, Place>();
});
All standard stuff. Has anyone else managed to get something similar working?
Your poco 'Place' is called 'PlaceRealm'. I suspect that is a typo. (made edit)
I suspect that Automapper is instantiating a new object overwriting your original 'placeRealm' object.
Perhaps you could try
Mapper.Map(place, placeRealm);
in place of your current mapping.
which should just copy the values to your already instatiated and tracked object.
(no need to store the return value).
You might also want to make explicit which properties (3) you are mapping as currently Automapper will map all including those in the base class.
On a side note, you may run into performance issues with Automapper. I found it to be the performance bottleneck in some apps. ExpressMapper is a nice alternative.

Orchard CMS: Updating a driver for a table with payload

I am new to Orchard and have gone through the advanced pluralsight course (which I thought was great). I have built the movie module, which can also be downloaded from the Orchard gallery, but I wanted to add a field for the actor's character name in a given movie. I decided this would fit on the MovieActorRecord so it becomes
public class MovieActorRecord {
public virtual int Id { get; set; }
public virtual MoviePartRecord MoviePartRecord { get; set; }
public virtual ActorRecord ActorRecord { get; set; }
public virtual string CharacterName { get; set; } }
I also added "CharacterName" to the MovieEditViewModel file. I'm unsure how to wire it all together in the MoviePartDriver when I'm building that viewmodel.
Can anyone help me through this?
Just add a migration step that alters the table to add the new column.

Resources