Xamarin Setting default Boolean value - xamarin.forms

I am using sqlite-net-pcl and adding a new column to a database DTO and I wanted to set the default value to true and then once I have update the data it would update to the correct value. But the default is not working for me in xamarin.
is there any other way to do this?
[NotNull]
public boolean Istaxable { get; set; } = true;
This will block me from doing a update.
[NotNull, Default(value: true)]
Error default is unknown
DTO
public class DtoTaxableLink
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[NotNull]
public bool IsTaxable { get; set; } = true;
}
service
await App.LocalDB.InsertTaxableLinksAsync(BuildDbTaxableLinkItem( public Task<int> InsertTaxableLinksAsync(List<DtoTaxableLink> taxableLinks)
ListResponse.Data));
local db
public Task<int> InsertTaxableLinksAsync(List<DtoTaxableLink> taxableLinks)
{
return database.InsertAllAsync(taxableLinks, true);
}
Helper
private static List<DtoTaxableLink> BuildDbTaxableLinkItem(List<TaxablelineLink> taxableLinks)
{
List<DtoTaxableLink> dtoTaxableLink= new List<DtoTaxableLink>();
foreach (var taxink in taxableLinks)
{
DtoTaxableLink dtoTaxableLink= new DtoTaxableLink();
dtoTaxableLink.IsTaxable = taxableLinks.IsTaxable ;
dtoTaxableLink.Add(dtoTaxableLink);
}
return dtoTaxableLink;
}

According to your description, you want to set the default value to true when using sqlite-net-pcl and adding a new column to a database.
You can do it through property itself, field default value not going change until another value going to set.Please take a look the following code:
public class User
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string userName { get; set; }
public string password { get; set; }
private bool _sel = true;
[NotNull]
public bool Selected
{
get { return _sel; }
set { _sel = value; }
}
}
Now you can see I set Selected property default value is True, then you can update this value that you want.

Related

Xamarin Forms SQLLite add OneToOne and OneToMany subobjects to db

Im trying to create a persistent sqllite db (creation tables once you install the app, deletion of db when you uninstall app)
I have a issue that I cant save my sub objects for example
public class ObjectInstanceResponseModel : GenericResponseModel
{
public ObservableCollection<ObjectInstanceData> ObjectInstances { get; set; }
}
public class ObjectInstanceData : GenericResponseModel
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[JsonProperty("idObjectinstance")]
public int IdObjectInstance { get; set; }
[JsonProperty("objectclass_idObjectclass")]
public int ObjectClassIdObjectClass { get; set; }
[JsonProperty("objectclassname")]
public string ObjectClassName { get; set; }
[JsonProperty("visibilitylevel")]
public int VisibilityLevel { get; set; }
[JsonProperty("showname")]
public bool ShowName { get; set; }
[JsonProperty("showicon")]
public bool ShowIcon { get; set; }
[JsonProperty("creationtime")]
public DateTimeOffset CreationTime { get; set; }
[JsonProperty("users_idUsers")]
public int UsersIdUsers { get; set; }
[JsonProperty("isfavorite")]
public bool? IsFavorite { get; set; }
[OneToMany("ObjectInstanceDataStrings")]
[JsonProperty("strings")]
public List<String> Strings { get; set; }
}
public class String
{
[PrimaryKey, AutoIncrement]
[JsonProperty("idObjectparameterstring")]
public int? IdObjectParameterString { get; set; }
[ForeignKey(typeof(ObjectInstanceData))]
public int ObjectInstanceDataStrings { get; set; }
[JsonProperty("stringvalue")]
public string StringValue { get; set; }
[JsonProperty("objectparameterset_idObjectparameterset")]
public int? ObjectParameterSetIdObjectParameterSet { get; set; }
[JsonProperty("showinballon")]
public bool? ShowInBallon { get; set; }
[JsonProperty("idClassparameter")]
public int IdClassParameter { get; set; }
[JsonProperty("classparametername")]
public string ClassParameterName { get; set; }
}
So, my class String is always empty, although there are some rows in the table that I created Strings..
Am I need a lazy loading for this?
I implemented sqllite through depedency service in my app.cs like this:
public partial class App : Application
{
public static SQLiteConnection DatabaseConnection { get; set; }
public App()
{
InitializeComponent();
DatabaseConnection = DependencyService.Get<IConnection>().GetConnection();
CreateTables();
}
private void CreateTables()
{
DatabaseConnection.CreateTable<ObjectInstanceData>();
DatabaseConnection.CreateTable<Models.Objects.String>();
}
protected override void OnStart()
{
}
protected override void OnSleep()
{
}
protected override void OnResume()
{
}
}
So, basically the logic should be when no internet, work with sql lite (keep local changes), and when internet come back upload that changes that kept in db, and erase data from tables.
You noticed that Im using response model for api.
So, Im calling from my FavoriteObjectViewModel this:
var response = await ApiServiceProvider.GetObjectInstances(null, true);
and in the ApiServiceProvider:
public static async Task<ObjectInstanceResponseModel> GetObjectInstances(string queryString = null, bool? onlyFavorites = null)
{
HttpResponseMessage response;
response = await apiClient.GetAsync(objectInstancesEndpoint);
var resultContent = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<ObservableCollection<ObjectInstanceData>>(resultContent);
objectInstanceResponse.ObjectInstances = result;
//after each api call I need to update db
//delete previous data, and add fresh data from api
App.DatabaseConnection.DeleteAll<ObjectInstanceData>();
foreach (var item in result)
{
App.DatabaseConnection.Insert(item);
if (item.Strings != null && item.Strings.Count > 0)
App.DatabaseConnection.InsertAll(item.Strings);
}
//I only get the data for ObjectInstanceData, Strings model is empty!
var objectsResponseDb = App.DatabaseConnection.GetAllWithChildren<ObjectInstanceData>();
objectInstanceResponse.Succeeded = true;
return objectInstanceResponse;
}
So, my questions are:
If I create tables each time in App.cs is that mean, that I not store data, when user quit application, and re-enter again?
Why is the model Strings empty? When I invoke var strings = App.DatabaseConnection.GetAllWithChildren<Models.Objects.String>(); I can see that there is data?
What is the best approach for doing offline "logging"? maybe there is a some better nuget for sqllite?
I don't know much about persistent databases but one thing I can tell you for sure:you're approach is wrong.
You should create a separate class for the database's logic like creating tables and instantiating the connection along with other methods for manipulating data.
In the App class you can create a static resource of the database class which you can call it and make use of the methods in it.
I'm not very good with explaining but here it is a very basic example of how it should look:https://learn.microsoft.com/en-us/xamarin/get-started/tutorials/local-database/?tutorial-step=2&tabs=vswin.

How to create two foreign keys to the same table with SQLite in Xamari Form

I working in a project with Xamarin Form using C#. I'm trying to create two foreign keys to the same table, using this code:
[Table("Posts")]
public class Post
{
[PrimaryKey]
public long PostID { get; set; }
public string Name { get; set; }
public TypeEntity mode = null;
[ManyToOne(CascadeOperations = CascadeOperation.CascadeInsert)]
public TypeEntity Mode
{
get
{
return mode;
}
set
{
mode = value;
}
}
[ForeignKey(typeof(TypeEntity))]
public long ModeID { get; set; }
public TypeEntity level = null;
[ManyToOne(CascadeOperations = CascadeOperation.CascadeInsert)]
public TypeEntity Level
{
get
{
return level;
}
set
{
level = value;
}
}
[ForeignKey(typeof(TypeEntity))]
public long LevelID { get; set; }
}
[Table("Types")]
public class TypeEntity
{
[PrimaryKey]
public long TypeID { get; set; }
public string Code { get; set; }
public string Name { get; set; }
}
As you can see, the properties Mode and Level are type "TypeEntty", so I need to create the relations.
When I try to insert data, only "Mode" property is inserted ok, "Level" property stay null.
public abstract class BaseStore<T> where T : new()
{
public static SQLiteConnection sql;
public BaseStore()
{
sql = DependencyService.Get<ISQLite>().GetConnection();
Init();
}
public void Init()
{
sql.CreateTable<T>();
}
public void Insert(T entity)
{
sql.InsertWithChildren(entity);
}
}
I switched properties order, I added Level first than Mode, and Level got the value. It means, that SQLIte take only the first property to create the relation.
Does anyone know why this isn't working?
I'm working with SQLite.Net.Core-PCL 3.1.1 and SQLiteNetExtensions 2.1.0.
You have to manually specify which foreign key corresponds to each relation. To do so, pass the ForeignKey parameter in each ManyToOne attribute.
Can't test it right now, but it would probably look something like this:
[ManyToOne(ForeignKey = "ModeID", CascadeOperations = CascadeOperation.CascadeInsert)]
public TypeEntity Mode
(...)
[ManyToOne(ForeignKey = "LevelID", CascadeOperations = CascadeOperation.CascadeInsert)]
public TypeEntity Level

Clean way for updating object in a collection of abstract objects

As I'm developping an asp net core + ef core 2.0 with localized objects in my model, I adapted the solution provided in the following link to localize my objects link.
I'm now trying to find a clean way to update my collection of translation when updated object are received in the controller.
For the moment I have a step model class defined this way :
public class Step
{
//Native properties
public Guid ID { get; set; }
public string Name { get; set; }
public int Order { get; set; }
public string ScriptBlock { get; set; }
//Parent Step Navigation property
public Nullable<Guid> ParentStepID { get; set; }
public virtual Step ParentStep { get; set; }
//Collection of sub steps
public virtual ICollection<Step> SubSteps { get; set; }
//MUI Properties
public TranslationCollection<StepTranslation> Translations { get; set; }
public string Description { get; set; }
//{
// get { return Translations[CultureInfo.CurrentCulture].Description; }
// set { Translations[CultureInfo.CurrentCulture].Description = value; }
//}
public Step()
{
//ID = Guid.NewGuid();
Translations = new TranslationCollection<StepTranslation>();
}
}
public class StepTranslation : Translation<StepTranslation>
{
public Guid StepTranslationId { get; set; }
public string Description { get; set; }
public StepTranslation()
{
StepTranslationId = Guid.NewGuid();
}
}
Translation and translationCollection are the same as in the link
public class TranslationCollection<T> : Collection<T> where T : Translation<T>, new()
{
public T this[CultureInfo culture]
{
// indexer
}
public T this[string culture]
{
//indexer
}
public bool HasCulture(string culture)
{
return this.Any(x => x.CultureName == culture);
}
public bool HasCulture(CultureInfo culture)
{
return this.Any(x => x.CultureName == culture.Name);
}
}
public abstract class Translation<T> where T : Translation<T>, new()
{
public Guid Id { get; set; }
public string CultureName { get; set; }
protected Translation()
{
Id = Guid.NewGuid();
}
public bool HasProperty(string name)
{
return this.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Any(p => p.Name == name);
}
}
My issue in this sample is how to deal correctly with the PUT method and the Description property of my step controller. When it receive a Step object to update (which is done through a native c# client) only the string Description property of Step might have been created/updated/unchanged. So I have to update/create/do Nothing on the Description of the translation in the correct culture.
My first guess is to add in the TranslationCollection class a method in which I could pass the culture, the name of the property to update or not (Description in this case) and the value of the Description.
But as the TranslationCollection is a collection of abstract objects I don't even if this is a good idea and if it's possible.
If someone would have any advice on it (hoping I was clear enough) it would be great !
Finally answered my own question, and it was quite simple.
Just had to use the indexer like :
myobject.Translations[userLang].Name = value;

Created and Modified date issue

I was practicing User.Identity and timestamps functions in ASP.NET MVC 5,
So I created a student class filled some properties, I just wanted to test if it is capturing timestamps and userId, so user id is getting captured and datetime too, problem is whenever I'm editing a record and save it, its created date becomes Null and modified date is updated, please review the code and help.
Thanks in advance.
Below is the Code
{
public class BaseEntity
{
public DateTime? DateCreated { get; set; }
public string UserCreated { get; set; }
public DateTime? DateModified { get; set; }
public string UserModified { get; set; }
}
public class Student : BaseEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string Subject { get; set; }
public string Class { get; set; }
public Section Section { get; set; }
public byte SectionId { get; set; }
}
then I used Codefirst approach and created an application Database and added this code in Identity Model
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<Student> Students { get; set; }
public override int SaveChanges()
{
AddTimestamps();
return base.SaveChanges();
}
//public override async Task<int> SaveChangesAsync()
//{
// AddTimestamps();
// return await base.SaveChangesAsync();
//}
private void AddTimestamps()
{
var entities = ChangeTracker.Entries().Where(x => x.Entity is BaseEntity && (x.State == EntityState.Added || x.State == EntityState.Modified));
var currentUsername = !string.IsNullOrEmpty(System.Web.HttpContext.Current?.User?.Identity?.Name)
? HttpContext.Current.User.Identity.Name
: "Anonymous";
foreach (var entity in entities)
{
if (entity.State == EntityState.Added)
{
((BaseEntity)entity.Entity).DateCreated = DateTime.UtcNow;
((BaseEntity)entity.Entity).UserCreated = currentUsername;
}
else
((BaseEntity)entity.Entity).DateModified = DateTime.UtcNow;
((BaseEntity)entity.Entity).UserModified = currentUsername;
}
}
public DbSet<Section> Sections { get; set; }
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
I have created a simple controller with create,edit and dispay actions.
The code you posted doesn't show DateCreated being set to null as far as I can see. I think the issue is when you save an existing record you do not have the DateCreated or UserCreated fields in your view. So when you post the form the MVC model binder doesn't see them and thus sets them to null (I'm assuming your are binding to the Student model in your controller action).
In your edit view add the following hidden fields:
#Html.HiddenFor(model => model.DateCreated)
#Html.HiddenFor(model => model.UserCreated)
Now when you post the form the MVC model binder will bind these values to your model and save them to the database.

How do you do lookup tables via code first

I've been searching this without any luck on how to resolve. I have a list of available departments that can be used within my stores. Since stores vary, some departments may not exist and I want to keep track of how much shelving space each department has for each store. What's the best way to create this?
Here's my model:
public class Store
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; } //StoreNumber
public virtual List<StoreDepartment> StoreDepartments { get; set; }
}
public class StoreDepartment
{
[Key]
public int ID { get; set; }
public int StoreID { get; set; }
public Department Department { get; set; }
public int ShelvingLinealFT { get; set; }
}
public class Department
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; } //DepartmentNumber
public string Name { get; set; }
public bool InActive { get; set; }
}
I've already populated my Department tables, but when I attempt to save a StoreDepartment object, I get an error stating that it can't insert a row since its trying to create a duplicate key. It's like it's trying to create a new record.
Any help would be appreciated.
Here's the code for my DbContext:
public class StoresRepository:DbContext
{
public DbSet<Store> Stores { get; set; }
public DbSet<StoreDepartment> StoreDepartments { get; set; }
public DbSet<Department> Departments { get; set; }
}
Here is my Save method:
/// <summary>
/// Saves a StoreDepartment Object to the store("dept.storeid")
/// Adds a new record if ID is 0
/// </summary>
/// <param name="dept"></param>
/// <returns></returns>
public bool Save(StoreDepartment dept)
{
bool retval = false;
try
{
using (var db = new StoresRepository())
{
if (dept.ID.Equals(0))
{
//Add Store Department
db.StoreDepartments.Add(dept);
}
else
{
//this is an update
StoreDepartment department = db.StoreDepartments.Where(p => p.ID.Equals(dept.ID)).FirstOrDefault();
department.Department = dept.Department;
department.ShelvingLinealFT = dept.ShelvingLinealFT;
}
int rowsupdated = db.SaveChanges();
retval = true;
}
}
catch (Exception ex)
{
Utils.Trace(string.Format("StoresContext.cs: StoreDepartments.Save(). ID:{1}. Exception: {0}", ex, dept.ID), Utils.ErrorTypes.Error);
}
return retval;
}
You probably change the state of the Department to added when you add the StoreDepartment object. Something like this:
using(var db = new MyContext())
{
var storeDepartment = new StoreDepartment();
storeDepartment.StoreId = storeId;
storeDeparemtent.Department = department;
db.StoreDepartments.Add(storeDepartment); // also marks Department as added
db.SaveChanges();
}
The solution is to move up the line where you add the object:
using(var db = new MyContext())
{
var storeDepartment = new StoreDepartment();
db.StoreDepartments.Add(storeDepartment);
storeDepartment.StoreId = storeId;
....
}
You can also add a DepartmentId to the StoreDepartment class and set its value, as you do with StoreId. Together with the Department property this is called a foreign key association.
I figured it out.
Here are the correct models:
public class StoreDepartment
{
[Key]
public int ID { get; set; }
public int DepartmentID { get; set; }
public virtual Department Department { get; set; }
public int ShelvingFootage { get; set; }
}
public class Department
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
public virtual ICollection<StoreDepartment> StoreDepartments { get; set; }
}
Using Affluent API, I setup my relationships as follows:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<StoreDepartment>().HasRequired(d => d.Department);
modelBuilder.Entity<Department>().HasMany(d => d.StoreDepartments);
}
Once I had this setup, one of the main issues I had was with populating the object.
Normally, you would do the following:
StoreDepartment sd = new StoreDepartment();
sd.Department = new Department(){
ID = 302,
Name = "Deli"
};
sd.ShelvingFootage = 100;
However when trying to save this object, Entity would attempt to add a new record in the Department table which of course would throw an exception due to a violation in the primary key.
The trick was to not update this directly and to build my StoreDepartment object as follows:
StoreDepartment sd = new StoreDepartment();
sd.DepartmentID = 302;
sd.ShelvingFootage = 100;
By doing this, you are only updating the foreign key for the StoreDepartment.Department object.

Resources