How do I save Xamarin TimePicker value to database? - sqlite

I'm using SQLite to store data from a Xamarin.Forms app. I want the user to be able to use the DatePicker for a date and the TimePicker for a time and then store it. When I use the following:
<DatePicker Date="{Binding Date}"
x:Name="DatePicker"
Format="D" />
It stores the chosen date in the database correctly but when I use:
<TimePicker Time="{Binding Time}"
x:Name="TimePicker"
Format="T"/>
It stores the time as 12:00 AM every time. What am I missing?
Date and Time are both DateTime values in the database.
using System;
using SQLite;
namespace Items.Models
{
public class Item
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Location { get; set; }
public DateTime Date { get; set; } = DateTime.Now;
public DateTime Time { get; set; }
}
and
using System.Collections.Generic;
using System.Threading.Tasks;
using SQLite;
using Items.Models;
namespace Item.Data
{
public class ItemDatabase
{
readonly SQLiteAsyncConnection database;
public ItemDatabase(string dbPath)
{
database = new SQLiteAsyncConnection(dbPath);
database.CreateTableAsync<Item>().Wait();
}
public Task<List<Item>> GetItemsAsync()
{
//Get all items.
return database.Table<Item>().ToListAsync();
}
public Task<Item> GetItemAsync(int id)
{
// Get a specific item.
return database.Table<Item>()
.Where(i => i.ID == id)
.FirstOrDefaultAsync();
}
public Task<int> SaveItemAsync(Item item)
{
if (item.ID != 0)
{
// Update an existing item.
return database.UpdateAsync(item);
}
else
{
// Save a new item.
return database.InsertAsync(item);
}
}
public Task<int> DeleteItemAsync(Item item)
{
// Delete an Item.
return database.DeleteAsync(item);
}
}
}

You got it wrong the type of TimePicker.Time, it should be TimeSpan not DateTime , so the binding is created incorrectly, that is the reason why the value not change when select the time on TimePicker .
Modify your code as below
public class Item
{
public DateTime Date { get; set; } = DateTime.Now;
public TimeSpan Time { get; set; }
}

Related

Xamarin Setting default Boolean value

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.

Xamarin Forms: How to select all items from local DB in the sorted order of time

I have implemented local DB in my project and I am using the following code to select all the items from local DB having a particular webContentId.
public List<Messages> GetAllItemsByWebContentId(string webContentId)
{
lock (locker)
{
return database.Table<Messages>().Where(o => o.webContentDefinitionId == webContentId).ToList();
}
}
Messages is my model class.
public class Messages
{
public Messages()
{
}
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public int tweetId { get; set; }
public string profileImage { get; set; }
public string name { get; set; }
public long createdTime { get; set; }
public string tweetData { get; set; }
public string mediaUrl { get; set; }
public string webContentDefinitionId { get; set; }
}
Now I need to sort this list in the order of createdTime. My createdTime is a 13 digit java timestamp. One example created time is 1543608245696, which means 01/12/2018 01:34. Without sorting, the latest messages are coming on the last of the local database. So inside of GetAllItemsByWebContentId() how can I add created time sorting?
Very easy!
change your code to:
return database.Table<Messages>()
.Where(o => o.webContentDefinitionId == webContentId)
.OrderByDescending(x => x.CreatedTime)
.ToList();

how to resolve 'DataSet does not support System.Nullable<>.'?

My goal is to export data to a pdf file using crystal report and entity framework but unfortunately, I have been receiving this error message when I try to run my code.
'System.NotSupportedException: 'DataSet does not support System.Nullable<>.'
Can anyone please kindly assist me?
This is what I have tried so far on my controller side
using System.Data.Entity;
using System.IO;
using Final_INF271.Reports;
using CrystalDecisions.CrystalReports.Engine;
public ActionResult Export()
{
ReportDocument rd = new ReportDocument();
rd.Load(Path.Combine(Server.MapPath("~/Reports/OutstandingOrders.rpt")));
rd.SetDataSource(db.ProductOrder.Select(p => new
{
p.OrderID,
p.Date,
p.SupplierID,
p.CostPrice,
p.Quantity
}).ToList());
Response.Buffer = false;
Response.ClearContent();
Response.ClearHeaders();
Stream stream = rd.ExportToStream
(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
stream.Seek(0, SeekOrigin.Begin);
return File(stream, "application/pdf", "OutstandingOrders");
}
Included is my ProductOrder
namespace Final_INF271.Models
{
using System;
using System.Collections.Generic;
public partial class ProductOrder
{
public int OrderID { get; set; }
public Nullable<System.DateTime> Date { get; set; }
public Nullable<int> EmployeeID { get; set; }
public Nullable<int> SupplierID { get; set; }
public int ProductTypeID { get; set; }
public Nullable<decimal> CostPrice { get; set; }
public Nullable<int> Quantity { get; set; }
public virtual Employee Employee { get; set; }
public virtual ProductType ProductType { get; set; }
public virtual Supplier Supplier { get; set; }
}
}
below is a picture of Data set and error message
Crystal Reports' SetDataSource() method creates DataColumn supplied by list of ProductOrder, and then trying to build DataColumn instances that has nullable type, which is not supported.
You should either create a viewmodel class which has properties with same base types but without nullable types present, then project the result with that class as data source:
// Viewmodel
public class ProductOrderVM
{
public int OrderID { get; set; }
public DateTime Date { get; set; }
public int SupplierID { get; set; }
public decimal CostPrice { get; set; }
public int Quantity { get; set; }
}
// Controller action
rd.SetDataSource(db.ProductOrder.Select(p => new ProductOrderVM
{
OrderID = p.OrderID,
Date = p.Date.GetValueOrDefault(),
SupplierID = p.SupplierID.GetValueOrDefault(),
CostPrice = p.CostPrice.GetValueOrDefault(),
Quantity = p.Quantity.GetValueOrDefault()
}).ToList());
Or use null coalescing/ternary operator to assign default values according to their base type if the nullable properties have null value:
rd.SetDataSource(db.ProductOrder.Select(p => new
{
OrderID = p.OrderID,
// with ternary operator
Date = p.Date == null ? DateTime.MinValue : p.Date, // or DateTime.Now as default value
// with null-coalescing operator
SupplierID = p.SupplierID ?? 0,
CostPrice = p.CostPrice ?? 0,
Quantity = p.Quantity ?? 0
}).ToList());

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 to join my tables with identity tables?

I started a default MVC project with Identity and EF.
In my app users will be able to create and edit some records.
In the table for these records, I want to have the ids of users who created the record and who updated lastly.
My model class is like:
public class Record
{
public int ID { get; set; }
public DateTime CreateTime { get; set; }
public string CreatingUserID { get; set; }
public string UpdatingUserID { get; set; }
public DateTime UpdateTime { get; set; }
public Enums.RecordStatus Status { get; set; }
}
And in RecordsController, I save new records to db like this:
[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FormCollection form, RecordCreateVM vm)
{
string userId = User.Identity.GetUserId();
DateTime now = DateTime.Now;
Record rec = new Record ();
if (ModelState.IsValid)
{
int newRecordId;
using (RecordRepository wr = new RecordRepository())
{
UpdateModel(rec);
rec.CreateTime = now;
rec.UpdateTime = now;
rec.CreatingUserID = userId;
rec.UpdatingUserID = userId;
rec.Status = Enums.RecordStatus.Active;
Record result = wr.Add(rec);
wr.SaveChanges();
newRecordId = result.ID;
}
}
}
When I am listing these records, I also want my page to display these users' usernames.
I get all the active records from the repository I created.
public ActionResult Index()
{
RecordListVMviewModel = new RecordListVM();
using (RecordRepository wr = new (RecordRepository())
{
viewModel.Records = wr.GetAll();
}
return View(viewModel);
}
And this is the repository code:
public class RecordRepository: Repository<Record>
{
public override List<Record> GetAll()
{
IQueryable<Record> activeRecords = DbSet.Where(w => w.Status == Enums.RecordStatus.Active);
return activeRecords.ToList();
}
}
Where do I have to make changes? Can you give me an sample code for usages like this?
Thank you.
You need to change
public string CreatingUserID { get; set; }
public string UpdatingUserID { get; set; }
to something like:
public User CreatingUser { get; set; }
public User UpdatingUser { get; set; }
Set the ID's during the creation of new RecordRepository()
Then access them as Record.CreatingUser.FirstName ect

Resources