Xamarin sqlite mapping models to database table - c#

I have deployed a database file for a xamarin project using the following guide. http://arteksoftware.com/deploying-a-database-file-with-a-xamarin-forms-app/
I created a model class as such:
[Table ("Person")]
public class Person
{
[PrimaryKey, AutoIncrement, Column("Id")]
public int Id { get; set; }
[NotNull, Column("Actor_Id")]
public int ActorId { get; set; }
}
When I try to do an insert in the repository
dbConn.Insert(newPerson);
I'm getting SQLite.Net.SQLiteException: table Person has no column named ActorId.
If the column name in the database is Actor_Id shouldn't the [Column] attribute in the model map it to the table.

There is a chance that your phone/emulator is previously deployed with app that with older database schema.
In this case, you will need to:
Remove the existing app in your phone/emulator. Then the next run should be OK due to it is created using new database schema. OR
Perform database upgrade script to change the schema of the current old database. Only do this if your app is already publish to store.

I found the problem to be that I was using the SQLite library in the model. Changing it to use SQLite.Net.Attributes allowed the correct mapping.
using SQLite.Net.Attributes;

Related

MVC Identity and Model classes

I'm trying to realize a MVC .NET core application with Identity scaffolded.
I stared from an empty MVC app, I added some Identity scaffolded items, with a specific IdentityDbContext and a specific IdentityUser:
public class MyCustomUser : IdentityUser
{
[PersonalData]
[Column(TypeName = "nvarchar(100)")]
public string FirstName { get; set; }
}
Then I created some custom model classes in the Models folder and I would like to force the EF to include those classes in the migration evoked with
Enable-Migrations
Add-Migration "MyMigration"
Update-Database
As a result I expect to see on my DB all the tables for the authentication (AspNetRoles, AspNetUsers (with its new column "FirstName") etc) and the tables created using the classes in \Models.
How can I achieve this?
Would you suggest another way to handle identity and models using EF?

Mobile Offline Sync database on Xamarin form

Currently looking at the Enable Offline Sync for Xamarin Form : https://learn.microsoft.com/en-us/azure/app-service-mobile/app-service-mobile-xamarin-forms-get-started-offline-data.
I am having the code running on mobile and the backend run and created ToDoList table with 2 entries. The table created in ToDoList has UpdateAt, Version and Deleted columns create from the controller which extends TableController.
In existing web application currently already using the database with tables, do I have to create all the tables with UpdateAt, Version and Deleted columns. I am unsure how this data generated for those columns in web application so that both mobile and web data can be consistent.
This free online book will go through details of getting the backend setup.
https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter3/dataconcepts/
One of the ways described is to you EF already built in Code-First with migrations, and have a base class that looks like this
public abstract class TableData
{
public string Id { get; set; }
public DateTimeOffset? UpdatedAt { get; set; }
public byte[] Version { get; set; }
}
Those are the table properties missing you asked about.

Why is the wrong DB being updated by EF6?

I'm trying to use EF6 in my project and I've got two databases I'm trying to interact with. My app.config has connection strings for both, and I have two DbContext classes that pass in the app.config's key for the corresponding connection string. One context:
public LogProcessorContext() : base("LogProcessorDb")
{
}
public DbSet<LogFile> LogFiles { get; set; }
the other context:
public MessageTrackingContext() : base("MessageTrackingDb")
{
}
public DbSet<JournalLog> JournalLogs { get; set; }
but when I add the migration using add-migration NewBranch and update the db, a log file table gets added to the message tracking db (the wrong one), and the journallogs table doesn't get added at all. If anyone has any experience getting ef to play nice with multiple db/contexts, i'm all ears. I'm sure its just some simple mistake I'm making.
btw,
"LogProcessorDb"
and
"MessageTrackingDb"
are the keys in my app.config for my connection strings.
Thanks!

Azure Mobile Services Identity Column Not Assigned While Offline

I'm using the Azure Mobile Services .NET backend with Xamarin.Forms and I'm having an issue with using int identity ID columns. When in an offline scenario, I can successfully add the record to the DB, but the CustomerId column which is an identity remains at 0. Once online, when I sync, the value is set by SQL server and populated on the mobile device.
As the ID is required as I also need to create related data in another table, the question is, how can I get/set an ID for an entity before it's sync'd with the server? I can't set it manually as it may clash with another client. I am suing an existing SQL database, so would prefer not to have to entirely change the scheme to change the ID to use strings or guid's.
public class Customer
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CustomerId { get; set; }
public string Name { get; set; }
....
}
public async Task SaveCustomer(Customer item) {
await CustomerTable.InsertAsync (item);
}
The scenario you are mentioning is exactly why Azure Mobile Apps uses strings for IDs. If you use a string, you can generate a GUID for the ID and use that prior to sync.
The only way to get the Id that is generated by the database is to sync the table.

How to recreate database in EF if my model changes?

I created a DbContext like so :
public class myDB : DbContext
{
public DbSet<Party> Parties { get; set; }
public DbSet<Booking> Bookings { get; set; }
}
This generated my DataBase and the two tables above..Great
I then decided to add another DbSet into the mix & I got an error:
the model backing the 'Party' context has changed since the database was created
I'm aware of the fixes for this using modelbuilder.IncludeMetadataInDatabase = false; and Database.SetInitializer<ClubmansGuideDB>(null);
1) What's the correct way to add my new classes to the context and have them generated in the DataBase?
2) In my futile attempts to solve this myself I deleted the tables and tried to re-run the app with no success I then deleted the full database and re-run and it doesn't re-generate the DB. How can I start from scratch - is there some cache somewhere?
I believe you're looking for:
Database.SetInitializer<ClubmansGuideDB>(new DropCreateDatabaseIfModelChanges<ClubmansGuideDB>());
As of EF 4.1 and above.
Note that this assumes you have permission to even drop your database. I do this locally for ease of development but disable it in staging/production (I do a manual Schema Compare and push my changes).
By the way, for testing, if you need to force recreate the database, you can do:
using (var context = new ClubmansGuideDB()) {
context.Database.Initialize(force: true);
}
(using if you don't already have a reference to your DB)
You can let the Entity Framework recreate the whole database by using a Database Initializer or if you want to migrate data you can look at the Code First Migrations
The following would recreate your database when the model changes:
Database.SetInitializer<myDB>(new DropCreateDatabaseIfModelChanges<myDB>());
Try putting this in your Global.asax.cs Application_Start() method.
Database.SetInitializer<DatabaseContext>(null);
To reset the database from scratch on app run make a class like this
//Where myDB is your context
public class EntityBase: DropCreateDatabaseAlways<myDB>
{
}
Then in your Application_Start() method you can do this
Database.SetInitializer(new EntityBase());

Categories